Archive | java
Easier Unit Testing in Spring
If you are using the Spring Framework, you should using Spring’s JUnit-based testing framework. See their docs for details.
I’ll try to do a summary for the rest of what it is and why you would want to use it instead of plain JUnit.
Here is a skeleton of the unit test class:
// AbstractDependencyInjectionSpringContextTests is in spring-mock.jarpublic class TestMyClass extends AbstractDependencyInjectionSpringContextTests { // classID must match the a bean ID in your Spring Configuration protected MyClass classID; // use the constructor just like the setUp method in JUnit public TestMyClass() { // this will populate all the protected objects setPopulateProtectedVariables(true); // this will find the class by name (i.e. bean ID) as opposed // to class-type setAutowireMode(AbstractDependencyInjectionSpringContextTests.AUTOWIRE_BY_NAME); } // this tells this class where to find the Spring configuration protected String[] getConfigLocations() { return new String[] { "classpath:appConfig.xml" }; } //** put your tests here public void testNormal(){ classID.someMethod(); // .... }
The AbstractDependencyInjectionSpringContextTests that TestMyClass extends has some very cool features. As the comments in the class above state, the protected classID object will automatically be populated with a new MyClass object – no need to fetch an ApplicationContext, get a bean, cast it, and then test it. If you want an ApplicationContext, the AbstractDependencyInjectionSpringContextTests gives you an instance called applicationContext that already is instantiated.
Did I mention that AbstractDependencyInjectionSpringContextTests is actually a subclass of JUnit’s TestCase? So you can still use the unit testing functionality in Eclipse and the junit tasks in ant.
I haven’t messed with it yet, but Spring also has an object called AbstractTransactionalDataSourceSpringContextTests that lets you poke around at the database within a test, rollback transactions, etc. Read more about it
in the Spring Docs.
Powered by ScribeFire.
Getting Spring To Read Your Log4j Config
I’m using [The Spring Framework](http://www.springframework.org/) to build a new application. Spring is cool — it can do a lot and there is a lot to learn about it. One cool thing I just figured out it [logging injection](http://www.devx.com/Java/Article/30799). One thing that took me a while to figure out is to get Spring (and my Spring-configured classes) to use my `log4j.xml` file instead of the `log4j.properties` that is hidden somewhere in the Spring jar.
I googled and googled and finally put together a couple of answers and got it to work. So now I’m putting it here so you, gentle reader, don’t have to go through that much work:
class=”org.springframework.beans.factory.config.MethodInvokingFactoryBean”>
Note that this is pretty much a boiler-plate — just copy it into your context configuration and make sure that your `log4j.xml` file is somewhere on your classpath. Then things will start working wonderfully
Find (and Fix) bugs with FindBugs
My co-workers have been buzzing about FindBugs for few weeks and it seems cool in theory. Well, our Lead sent an email out yesterday that we all need to start using it in our development cycle and, since I was waiting for other people to get back to me, I hesitatingly gave it a try.
Hesitatingly, you say? Is this because you want to face your bugs? Not at all — I freely admit that I write buggy programs and I will say that all other programmers do as well. But I was hesitate because I knew that it would find tons of problems. You see, I’m just the latest developer on this application and, from what I gather from the source, there has been at least six programmers before me working on this. Quite a few of them have at zero idea of what the overall picture was of this app and so they just put code in and hoped for the best. And some of those developers decided to take that code they just put in and copy-and-paste it all over the place. One section of bad code can be dealt with, but when the exact same thing is repeated ten times, it gets hard to go through. But the code works and so it’s difficult to try to refactor it into something more manageable. If it ain’t broke don’t fix it.
So I ran FindBugs and it was just as bad as I thought it was going to be. A few things were “Oh, I would have never caught that.” and some were honestly no big deal, but most of them were “Why would you do that?” And most of those were caused by bad code someone had written and the copied-and-pasted it several times. In a few cases, about 50 times.
Here are three of my favorite bad patterns that I have corrected:
if (nodelist==null && nodelist.getLength()<=0)This doesn’t look bad at first until you realize that if the first condition is true, you will get aNullPointerExceptionwhen the second condition is executed. This was an easy fix — change the&&to||.-
if (item==null) { object.setValue(item); }Why would you make sure an object is null and then set a property to it? I safely assumed they didn’t really want to do this the 20 times it happened.
- This one occured in two ways:
object.setValue(txt.toString());orobject.setValue(new String(txt));This isn’t a bug per-se. It’s not going to cause an exception, but turning a String into a String is a waste of cycles and memory. Not a big deal if it happens once or twice. But I changed many, many, many of these. Inside large loops.
So if you are working on a old Java project and have some time on your hands, run FindBugs and find all the mistakes you or your predecessors have made.
Powered by ScribeFire.
Java, Strings, and Words — oh my
My problem seemed easy — I want to capitalize the words in a sentence. So “FRANK BURNS EATS WORMS” become “Frank Burns Eats Worms”. And I wrote a little method that did that and life was good.
But then I realized that I also had strings like “M.A. HOSTETLER (COMPUTER GEEK)” and they would come out to “M.a. Hostetler (COMPUTER GEEK)”. Hm, not quite what I wanted. I googled around and found nothing. A few more, generic searches later and I found <code>WordUtils</code> in common-lang. Yeah, I already had common-lang in my project since it was a dependency for something else! Well, why not try it! Surely the Apache Commons people were smarter than me!
Nope, nadda. They seemed to be as smart as I am on this issue. Well. maybe a little bit smarter because the capitalizeFully method could take an array of characters as word delimiters. So I got a game plan in my head that seemed easy and, after many tries got something that worked. Not optimal, mind you, but working.
public static String capWords(String str){
return capWords(str," ");
}
public static String capWords(String str, String delimiter) {
String[] strList = str.split(delimiter);
ArrayList new_strs = new ArrayList();
Pattern non_alpha = Pattern.compile("W");
for(int i=0; i<strList.length; i++ ) {
String mystr = strList[i];
Matcher match = non_alpha.matcher(mystr);
String mark = null;
if (match.find()) {
int idx = match.start();
mark = mystr.substring(idx,idx+1);
} else {
mark=delimiter;
}
new_strs.add(WordUtils.capitalizeFully(mystr, mark.toCharArray()));
}
return strJoin(new_strs,delimiter);
}
Now I can correctly get “M.A. Hostetler (Computer Geek)”, just like I want it to be.
The new method lets the WordUtils class do it’s thing, but I just feed it different delimiters. Of course, the delimiters are hard-coded and I probably didn’t even need to use the space as a special case, but it’s the most common delimiter. Using a space as delimiter one and then the punctuation, etc., after that stops us from dividing too much too soon.
This just proves Joel Spotsky’s statement — strings are hard.
Powered by ScribeFire.
Treating a log4j log like a database
I’m finally posting a Python module I wrote months ago that I have found to be very handy.
Our log4j log files get big — really big. It doesn’t help that we log just about everything under the sun. This makes it difficult to parse through and find the messages that we are looking for. I got to thinking, “With these set fields, the log files are really just a database. Why can’t I query like that?” I know that Chainsaw does something like this, but I wanted to put it into my own scripts. Python scripts, that is.
Thus loginfo.py was born. This module contains one class called LogInfo that parses the log and then lets you do simple queries on it. So you can grab all INFO messages, all messages containing a certain word, or all messages in X hours or minutes ago. You can also chain these queries — so you can get all INFO messages that occurred in the past 4 hours.
Need an example? Here is the example in the module:
lfile = file(sys.argv[1]) log = LogInfo() for x in lfile.readlines(): log.addEntry(x) ## prints out all error messages from the past eight hours for msg in log.error().hoursAgo(8): print msg['date'],msg['sev'],msg['class'],msg['message']
Simple, huh? Grab the module here: loginfo.py
