Scott Leberknight

All | General | Java | Ruby | .NET | Groovy
XML
20080625 Wednesday June 25, 2008
Groovy Fun With ObjectRange

I ran into a situation the other day with Groovy that baffled me at first. Let's create a range from 0.0 to 10.0 and then use it to check if a certain number is contained within that range, like this:

groovy:000> r = 0.0..10.0
===> 0.0..10.0
groovy:000> r.contains(5.6)
===> false

WTF? The number 5.6 is not contained in the range 0.0 to 10.0? I beg to differ. So what's actually going on here? Using the shell we can do some more digging, interrogating the range object to see what its bounds are, what values it contains if you iterate it, and so on:

groovy:000> r = 0.0..10.0
===> 0.0..10.0
groovy:000> r.class
===> class groovy.lang.ObjectRange
groovy:000> r.from.class
===> class java.math.BigDecimal
groovy:000> r.to.class
===> class java.math.BigDecimal
groovy:000> r.each { print " $it " }  
 0.0  1.0  2.0  3.0  4.0  5.0  6.0  7.0  8.0  9.0  10.0 ===> 0.0..10.0
groovy:000> r.contains 5 
===> true
groovy:000> r.contains 5.0
===> true
groovy:000> r.contains 5.6
===> false

So what did we learn? First, the range is an ObjectRange whose bounds are BigDecimals. Second, that iterating by default iterates in increments of one. And third that the contains method does not quite do what I would expect by default. Looking at Groovy's ObjectRange class makes it clear exactly what's going on, so let's look:

public boolean contains(Object value) {
  Iterator it = iterator();
  if (value == null) return false;
  while (it.hasNext()) {
    try {
      if (DefaultTypeTransformation.compareEqual(value, it.next())) return true;
    } catch (ClassCastException e) {
      return false;
    }
  }
  return false;
}

The Groovy ObjectRange's contains method defines containment as whether a value is contained within the values generated by its iterator. By now many of my many millions of readers are about to post a comment telling me the problem, so I'll preempt that temptation by adding a few more lines of interaction with the Groovy shell:

groovy:000> r.containsWithinBounds 5.0
===> true
groovy:000> r.containsWithinBounds 5.6
===> true

Aha! So contains doesn't do what you might think it should, but containsWithinBounds does. Its JavaDoc says "Checks whether a value is between the from and to values of a Range." Conspicuously there is no JavaDoc on the contains method to tell me that what it actually does is check whether a value is contained within the discrete values generated by the iterator. Let's try more more thing:

groovy:000> r.containsWithinBounds 5
ERROR java.lang.ClassCastException: java.lang.Integer
        at groovysh_evaluate.run (groovysh_evaluate:2)
        ...

Oops! Not only do you need to call containsWithinBounds rather than contains, you also need to call it with the correct type, as there is no coercion going on since it uses Comparable.compareTo() under the covers.

Notwithstanding all the recent activity regarding all the Ruby security flaws recently discovered, how does Ruby handle inclusion of a number within a range? Here's some irb output:

>> r = 0.0..10.0
=> 0.0..10.0
>> r.class
=> Range
>> r.begin.class
=> Float
>> r.end.class
=> Float
>> r.each { |item| print " #{item} " }
TypeError: can't iterate from Float
        from (irb):53:in `each'
        from (irb):53
>> r.include? 5
=> true
>> r.include? 5.0
=> true
>> r.include? 5.6
=> true

To me this is more semantically and intuitively correct behavior. First, while I can create a range with float bounds, I cannot iterate that range - for non-integral numbers, how exactly can you define the next item after 0.0 for example? 0.1, 0.01, 0.001, and so on till infinity. Second, the include? method behaves as I would expect no matter what type of argument I pass. I am able to iterate ranges of integral numbers, however, which could arguably also be confusing since the behavior of the method depends on the type. Then again, that's pretty much what polymorphic method behavior is about I suppose.

>> r = 0..10
=> 0..10
>> r.each { |item| print " #{item} " }
 0  1  2  3  4  5  6  7  8  9  10 => 0..10

In the case of integers Ruby uses an increment of one by default. You could use the step method to get a different increment, e.g.:

>> r.step(2) { |item| print " #{item} " }
 0  2  4  6  8  10 => 0..10

So what's the point of all this? That Ruby is better than Groovy? Nope. I really like both languages. I think there are a couple of points that were reinforced to me:

First, RTFM (or source code --> RTFC). Even though Groovy's contains method doesn't behave how I think it should, there is the method I was looking for with containsWithinBounds.

Second, having a shell to play around with short snippets of code is really, really useful, without needing to create a class with a main method just to play around with code.

Third, documentation and semantics matter. If something doesn't feel intuitively correct based on how similar things act, it is more likely to cause confusion and errors. In this case, since my unit test immediately caught the error, I was able to figure the problem out in a few minutes.

Finally, following on from the last point, unit tests continue to remain valuable. Of course anyone who knows me would roll their eyes over my anal-ness (which Mac's dictionary is telling me is not really a word but I don't care at the moment) expecting me to get something about unit testing in somehow.

Posted by sleberkn Jun 25 2008, 03:34:02 PM EDT
20080623 Monday June 23, 2008
Just How Does Spring Do Its Classpath Component Scanning Magic?

One really cool feature in Spring 2.5+ is classpath component scanning. For example, instead of manually defining and wiring up all the beans comprising your Spring-based application, you simply add a few "driver" snippets of XML to your application context configuration, and then annotate your component classes with @Component (or any specialization such as @Controller and @Service). I am calling the XML snippets a "driver" because all they do is enable a specific feature, such as classpath scanning or component autowiring:

<-- Enable autowiring via @Autowire annotations -->
<context:annotation-config/>

<-- Scan for components in a package (and its subpackages)  -->
<context:component-scan base-package="org.springframework.samples.petclinic.web"/>

After seeing this was pretty cool, I wanted to know how exactly they did the classpath scanning. It boils down to doing some gymnastics with class loaders and resource path matching and using the ClassLoader.getResources(String name) method which returns an Enumeration containing URLs representing classpath resources. Those resources (Java classes) are then checked to see if they contain the @Component annotation (or a specialization of it) and if so, are considered a "candidate" component. Other filtering can take place but by default those components are then defined programmatically as Spring beans. When annotation configuration is enabled, autowiring of components also takes place, so I can have Spring scan the classpath for all my web controllers, and then automatically inject dependencies such as services or data access objects. Cool!

The actual classes that perform this magic are the ClassPathScanningCandidateComponentProvider which, by default, uses a PathMatchingResourcePatternResolver to find matching classpath resources using ClassLoader.getResources(). As a quick example, you can see this in action by writing a simple script, like so:

ClassPathScanningCandidateComponentProvider provider =
    new ClassPathScanningCandidateComponentProvider(true);
String basePackage = "org/springframework/samples/petclinic";
Set<BeanDefinition> components = provider.findCandidateComponents(basePackage);
for (BeanDefinition component : components) {
    System.out.printf("Component: %s\n", component.getBeanClassName());
}

Running this code (using the PetClinic sample application shipped with Spring), you get the following output:

Component: org.springframework.samples.petclinic.hibernate.HibernateClinic
Component: org.springframework.samples.petclinic.jdbc.SimpleJdbcClinic
Component: org.springframework.samples.petclinic.jpa.EntityManagerClinic
Component: org.springframework.samples.petclinic.web.AddOwnerForm
Component: org.springframework.samples.petclinic.web.AddPetForm
Component: org.springframework.samples.petclinic.web.AddVisitForm
Component: org.springframework.samples.petclinic.web.ClinicController
Component: org.springframework.samples.petclinic.web.EditOwnerForm
Component: org.springframework.samples.petclinic.web.EditPetForm
Component: org.springframework.samples.petclinic.web.FindOwnersForm

For a more fun experiment, I tried to scan using "org" as the base package...

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at org.springframework.asm.ClassReader.a(Unknown Source)
	at org.springframework.asm.ClassReader.(Unknown Source)
	at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:76)
	at org.springframework.core.type.classreading.CachingMetadataReaderFactory.getMetadataReader(CachingMetadataReaderFactory.java:68)
	at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:181)
	at org.springframework.samples.petclinic.ClassPathScannerTester.main(ClassPathScannerTester.java:17)

Ok, so you need to restrict the scan space that Spring will use or else you could run out of memory scanning every possible class in your system! Regardless, with classpath scanning of components and autowiring of dependencies, you can cut down the amount of XML in Spring-based apps a lot.

Posted by sleberkn Jun 23 2008, 05:56:46 PM EDT
20080618 Wednesday June 18, 2008
Creating Executable JARs using the Maven Assembly Plugin

On a current project I needed to create an executable JAR that does a bunch of processing on collections of files. As with most projects, I rely on a bunch of open source tools as dependencies. Since, to my current knowledge anyway, there is no way to have JARs within JARs I needed a quick way to create an executable JAR containing all the required dependencies. I did a bunch of searching and asking around and eventually found the Maven Assembly Plugin. This plugin generates "assemblies" which could be just the executable JAR or could be an entire source distribution in multiple formats (e.g. zip, tar.gz, etc.).

The basics of the plugin are simple. Add the <plugin> to your Maven POM file, define the assembly, and for executable JARs specify the main class. Here's how I configured the plugin:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <descriptorRefs>
      <descriptorRef>jar-with-dependencies</descriptorRef>
    </descriptorRefs>
    <archive>
      <manifest>
        <mainClass>com.nearinfinity.arc2text.ARC2TextConverter</mainClass>
      </manifest>
    </archive>
  </configuration>
</plugin>

In the above, I used one of the conveniently predefined descriptor references, in this case "jar-with-dependencies" which does pretty much exactly as you would expect. You could also define your own assembly but that looked quite a bit more complicated and all I needed was to simply produce an executable JAR. When the assembly plugin executes the above example configuration, it creates a single executable JAR with all my classes and all the classes from all the dependencies. It also sets up the JAR manifest with the Main-Class that you specify. The dependencies, which in my case were all other JAR files, are extracted from their JARs and placed directly into the JAR file, i.e. the classes in the dependent JARs are extracted and then put into the new custom JAR. The plugin even copies over license files, e.g. LICENSE, ASM-LICENSE.txt, etc. into the META-INF directory in the JAR.

The only things left to do is use the plugin. To do that you can simply run the command:

mvn assembly:assembly

There are other goals in the assembly plugin but this is the main one you need. So if you need to create an executable JAR containing dependencies, this is a nice quick way to do it, especially if you were already using Maven.

Posted by sleberkn Jun 18 2008, 01:59:56 PM EDT
20080513 Tuesday May 13, 2008
Verify EasyMock Behavior When Expecting Exceptions

Often when writing unit tests I use EasyMock to mock dependencies of the class under test. And many times I need to test that a certain type of exception is thrown during a test. Sometimes I need both, for example I am using a mock to simulate a dependency that throws an exception and I want my test to verify the appropriate exception was indeed thrown and that the mock was called properly. In those cases, I use a simple little trick: use a try/finally block along with a JUnit "@Test(expected = FooException.class" annotation on my test method. Voila! Now you can verify mock behavior and verify the exception was thrown at the same time. This is cleaner than using a catch block and asserting the correct exception was thrown, since you rely on JUnit to verify the exception using the "expected" attribute of the @Test annotation. For example:

@Test(expected = ThrottleException.class)
public void testSomethingWithDependencies() {
    // Create mock
    Rocket mainBooster = createMock(Rocket.class);
	
    // Record behavior
    mainBooster.ignite();
    
    // Simluate an invalid call to 'throttleUp'
    expect(rocket.throttleUp(-10000L)).andThrow(ThrottleException.class);
    
    // Replay mock
    replay(rocket);
    
    // Create object with dependency on mainBooster
    SpaceShuttle shuttle = new SpaceShuttle(rocket);    
    
    // Now try to perform a 'blast off' and
    // verify the mock behavior was as expected
    try {
        shuttle.blastOff();
    }
    finally {
        verify(rocket);
    }
}

If instead of writing tests in Java you write them in Groovy, the above code could be a little bit Groovier, though not much. (In an earlier post I showed how you can write unit tests in Groovy and still use JUnit instead of GroovyTestCase if you like.)

@Test(expected = ThrottleException)
void testSomethingWithDependencies() {
    // Create mock
    def mainBooster = createMock(Rocket)
    
    // Record behavior
    mainBooster.ignite()
    
    // Simluate an invalid call to 'throttleUp'
    expect(rocket.throttleUp(-10000L)).andThrow(ThrottleException.class)
    
    // Replay mock
    replay rocket
    
    // Create object with dependency on mainBooster
    def shuttle = new SpaceShuttle(rocket)
    
    // Now try to perform a 'blast off' and
    // verify the mock behavior was as expected
    try {
        shuttle.blastOff()
    }
    finally {
        verify rocket
    }
}

Even more Groovy in this case would be to extend GroovyTestCase and use its shouldFail method, like so:

void testSomethingWithDependencies() {
    // Create mock
    def mainBooster = createMock(Rocket)
	
    // Record behavior
    mainBooster.ignite()
	
    // Simluate an invalid call to 'throttleUp'
    expect(rocket.throttleUp(-10000L)).andThrow(ThrottleException.class)
    
    // Replay mock
    replay rocket
    
    // Create object with dependency on mainBooster
    def shuttle = new SpaceShuttle(rocket)
    
    // Now try to perform a 'blast off' and
    // verify the mock behavior was as expected
    shouldFail(ThrottleException) {
        shuttle.blastOff()
    }
    verify rocket
}

The GroovyTestCase version is probably the cleanest of the above three options. If you're not into Groovy, you can still use the JUnit "@Test(expected = BarException.class)" together with a try/finally/verify in plain Java unit tests for a cleaner test experience.

Posted by sleberkn May 13 2008, 02:51:08 PM EDT
20080412 Saturday April 12, 2008
What Not To Show a User

Quick rule of thumb: Don't show users cryptic error messages. This one was an error I recently received at a major airline's web site while checking in online for a flight:

Internal Session Id 1207429769869209087112251146956
User Session Id H3qJ4YGjTnTH1Sv0d4nVMBNhr2vdn77m4MKGQ3MT0SVVhQQvsQBk!1447771105!1207429769869
telprdB UserIntB12 java.lang.NullPointerException

That's a lot more information than should be given out to anyone, and is certainly not "user friendly." Do you think they are using Java? That NPE didn't give it away did it? Then again you can pretty much figure that out from the ".do" on the end of the URLs they use, which is one reason why web frameworks these days allow you to map things in a more REST-friendly and technology-agnostic manner using *.html or something like /my/site/person/1. Another rule of thumb: design URLs to be technology agnostic and generic, so that just from a URL it cannot be determined what technology you are using and in case you need or want to switch to a different technology you could theoretically use the same routing scheme in your URLs, which would allow bookmarks to keep working.

Posted by sleberkn Apr 12 2008, 04:00:48 PM EDT
20080410 Thursday April 10, 2008
Cocoa Bootcamp at Big Nerd Ranch

Last week I went to the Cocoa Bootcamp at the Big Nerd Ranch. It was held outside Atlanta at the Historic Banning Mills country inn in Whitesburg, GA - pretty much in the woods in the middle of nowhere, which was nice because there were no distractions like when you go to training in a big city where you want to go out do things every night.

Historic Banning Mills

Aaron Hillegass taught the class and is the author of the excellent Cocoa Programming for Mac OS X which was actually what we used during the class all week. The bottom line for me was that this was the best training class I've ever attended. It was basically one week of intense learning and writing (lots and lots and lots of) code, as the class was way more hands-on than any other training I've attended. Aaron would show some slides on a topic, talk about the real-world implications, and then we were off working through the examples in the book with Aaron providing help and guidance along the way. Everyone in the class was extremely motivated to learn and Aaron (as well as Mark Fenoglio who was assisting Aaron and the students) was willing to stay late at night helping you out with the code labs and exercises.

At Big Nerd Ranch it goes like this: Wake up and go to a nice sit-down breakfast where you try not to eat too much of the good food they provide. Then you go downstairs to a nice classroom from 9am until 12:30pm and write lots of Cocoa code. After that you have more good food at lunch, have about an hour of training after lunch followed by an afternoon hike. Below is JavaScript (and Cocoa) Jedi Master Jason Harwig making his way on one of the hikes along with several other photos I took along the hikes.

Jason hiking

Hiking along the river:

River along hiking trail

An old mill along the river:

Old mill along hiking trail

The hike (and apparently swimming as well in the summer months) is a great way to break up the training day, refresh, and re-energize. Usually about that time in other training classes I would prefer to take a nap and require need a mass infusion of caffeine. But after the hikes I was ready for some more Cocoa! After the hike you go back and do some more learning/coding until about 6:30 when a nice country dinner is served. Good food and they provide free wine and beer, which is always a plus anywhere! After dinner many students actually go back to the training room and write code for several more hours and somehow you actually want to do it! In other training classes by about 5pm my brain is on the way out and I want to stop doing anything related to training. For some reason here, though, you seem to have more energy and drive to keep on coding.

I had a great time and am planning to go back and take more training there, probably the Python Bootcamp since I have been interested in Python for a few years now and have written some admin-type scripts for various projects I've been on as well as worked my way through a Python introductory book. Now that Google App Engine is available and that you currently must code in Python-only I am even more motivated to go and take this course. I'm hoping that as influential innovative companies like Google show that Java and .NET aren't the only game in town to "real" businesses, perhaps they'll be more willing to implement projects in more flexible and lightweight technologies.

Posted by sleberkn Apr 10 2008, 11:17:12 AM EDT
20080321 Friday March 21, 2008
JUnit4 Tests in Groovy

On my current (Java-based) project we now write all new unit tests in Groovy, though there are a lot of legacy Java tests still out there that we haven't had time or felt the need to convert to Groovy-based tests. There are also several base test classes, also written in Java, that provide some nice set up and tear down code for certain classes of test. I happened to be testing a web controller and realized I needed (or rather, wanted) to make use of the existing AbstractViewControllerTest base class, which is written in Java, uses JUnit4 annotations, and provides, among other things, code that creates and sets up a simulated authenticated user for the controller along with a bunch of other stuff like mock requests, responses, session, helper methods, etc. So, the problem was that I needed to extend AbstractViewControllerTest and not GroovyTestCase, and initially got all bent out of shape about having to choose to write the test in Java and extend the base test or write it in Groovy extending GroovyTestCase and having to redo the stuff already provided by the base class.

Thankfully about that time Steve reminded me nicely that you can mix-and-match Groovy and JUnit4 annotations just fine since Groovy has now sported annotation support for a while now (since ~1.1 I think). So I can simply write the test in Groovy, extend the base test class, and use JUnit4 annotations to get exactly what I want. What's the point? Just remember that when writing tests in Groovy there is nothing that says you must extend GroovyTestCase and that you can use JUnit4 in Groovy tests. So for example you could have a Groovy test like this:

class MyTest extends TestBaseClass {
    @Before
    void doSetup() { ... }
	
    @Test
    void testSomething() { ... }
	
    @Test(expected = IllegalArgumentException)
    void testBadThing() { ... }
}

This way you can extend some other class if you choose, and get all the normal JUnit4 stuff. Since you are not extending GroovyTestCase one thing that is missing is shouldFail() so instead you use the "expected" parameter in your @Test annotation when you want to verify a specific type of exception was thrown.

Posted by sleberkn Mar 21 2008, 09:03:10 AM EST
20080320 Thursday March 20, 2008
Wackiness With String, GString, and Equality in Groovy

We ran into this one today while writing a Groovy unit test. Check out the following GroovyShell session:

groovy:000> test = []
===> []
groovy:000> (1..10).each { test << "Item $it" }
===> 1..10
groovy:000> test                               
===> [Item 1, Item 2, Item 3, Item 4, Item 5, Item 6, Item 7, Item 8, Item 9, Item 10]
groovy:000> test.contains("Item 1")
===> false

Um...what? We started by adding items to a list, e.g. "Item 1", "Item 2", and so on. Then we simply ask whether the list contains an item we know (or think) is there. But no, it prints false! How can test possibly not contain "Item 1?" First, what's going on here? Look at this second example:

groovy:000> test = []
===> []
groovy:000> (1..10).each { test << "Item $it" }
===> 1..10
groovy:000> test
===> [Item 1, Item 2, Item 3, Item 4, Item 5, Item 6, Item 7, Item 8, Item 9, Item 10]
groovy:000> println test[0].class 
class org.codehaus.groovy.runtime.GStringImpl
===> null

Ah ha! The items in the list aren't strings. So what? Look at this code:

groovy:000> a = "Item 2"
===> Item 2
groovy:000> a.class
===> class java.lang.String
groovy:000> n = 2
===> 2
groovy:000> b = "Item $n"
===> Item 2
groovy:000> b.class
===> class org.codehaus.groovy.runtime.GStringImpl
groovy:000> a == b
===> true
groovy:000> b == a
===> true
groovy:000> a.equals(b)
===> false
groovy:000> b.equals(a)
===> false

a is a normal Java String, whereas b is a Groovy GString. Even more interesting (or perhaps confusing), a == comparison yields true, but a comparison using equals() is false! So back in the original example where we checked if the 'test' list contained 'Item 1', the contains() method (which comes from Java not Groovy) uses equals() to compare the values and responds that in fact, no, the list does not contain the String "Item 1." Without getting too much more detailed, how to fix this? Look at this example:

groovy:000> test = []
===> []
groovy:000> (1..10).each { test << "Item $it".toString() }
===> 1..10
groovy:000> test
===> [Item 1, Item 2, Item 3, Item 4, Item 5, Item 6, Item 7, Item 8, Item 9, Item 10]
groovy:000> test.contains('Item 1')
===> true

Now it returns true, since in the above example we explicitly forced evaluation of the GStrings in the list by calling toString(). The Groovy web site explains about GString lazy evaluation stating that "GString uses lazy evaluation so its not until the toString() method is invoked that the GString is evaluated."

Ok, so we now understand why the observed behavior happens. The second question is whether or not this is something likely to confuse the You-Know-What out of developers and whether it should behave differently. To me, this could easily lead to some subtle and difficult to find bugs and I think it should work like a developer expects without requiring an understanding of whether GStrings are lazily-evaluated or not. Lazy evaluation always seems to come at a price, for example in ORM frameworks it can easily result in the "n + 1 selects" problem.

For comparison, let's take a look at similar Ruby example in an irb session:

>> test = []
=> []
>> (1..10).each { |n| test << "Item #{n}" }
=> 1..10
>> test
=> ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10"]
>> test.include? "Item 1"
=> true

Ruby "does the right thing" from just looking at the code. Ruby 1, Groovy 0 on this one. I don't actually know whether Ruby strings evaluate the expressions immediately or not, and should not need to care. Code that looks simple should not require understanding the implementation strategy of a particular feature. Otherwise it is broken in my opinion.

Posted by sleberkn Mar 20 2008, 02:44:18 PM EST
20080319 Wednesday March 19, 2008
Dumping the Maven Groovy Plugin

On my current project we are using Maven2 (yeah, yeah I know) which I become less and less happy with over time. That's not the point of this blog though. The point is that we have been using the Groovy Maven Plugin for a few months now to compile tests written in Groovy. The project is a Java project but several months ago we started writing new tests entirely in Groovy. This has worked nicely for a while, until today in one test I wanted to use a static import, which Groovy 1.5.x supports just fine. Unfortunately it seems the Groovy Maven Plugin uses a much earlier version of Groovy which doesn't support static imports. After a lot of fiddling around trying to get the plugin to work, we simply gave up and went with using the Maven Ant plugin to compile the Groovy code instead. It actually works and now we know for sure that we are using Groovy version 1.5.4.

Posted by sleberkn Mar 19 2008, 04:07:51 PM EST
20080318 Tuesday March 18, 2008
Java Versus Ruby/Rails Books Revisited...It Was Only A Matter Of Time

Remember when the big joke was to compare the book stacks of a typical Java web developer with that of a Ruby/Rails developer?

Java Versus Ruby Book Stacks

I suppose it was only a matter of time, because now maybe the Ruby/Rails stack looks more like this:

Ruby and Rails Books circa 2008

By the way, I like and use Ruby/Rails and use Java among other languages like Python and Groovy so I am not comparing the actual technologies, just the available reading material. The real trend is that since the original Java vs. Ruby books stack images first appeared, Ruby/Rails have gained a lot of traction and people are naturally writing a lot more material to satisfy the demand. I should also note that shawn believes that you still only need the original two Pragmatic Programmer books Programming Ruby and Agile Web Development with Rails. Regardless, there are a lot more options available now and I've heard people say books like The Ruby Way and Rails Recipes are very good books as well. Ah the paradox of choice.

Image credits: Antonio Cangiano for the Ruby/Rails recommended books image, and garbett.org for the Java vs. Ruby book stack image.

Posted by sleberkn Mar 18 2008, 12:19:34 PM EST
20080220 Wednesday February 20, 2008
SecurityException Running Groovy Scripts with JetGroovy IntelliJ Plugin

Yesterday before leaving for home I happily upgraded the JetGroovy plugin to the latest and greatest version 1.0.14394 (on Mac OS X Leopard). Up until now, I've had great luck with this plug-in and have enjoyed using it to write Groovy code. Today, however, when I went to run several Groovy scripts I've been using while preparing a presentation, they failed with a rather nasty error:

java.lang.SecurityException: Prohibited package name: java.lang
...
...
...lots more stack trace gunk...

Uh oh. After doing some investigation on the JetBrains forums, the problem is that the JDK classes are being set in the Groovy classpath that IntelliJ passes to groovyStarter, which causes the security exception, presumably because Java thinks something is trying to add java.lang classes to the classpath. The issue is GRVY-1088 in JetBrains' JIRA tracker in case you are interested.

Fortunately a co-worker had not yet upgraded to the latest version and that version still works fine. In fact, that older version 1.0.14201 actually does not call groovyStarter but instead uses groovy.lang.GroovyShell to execute the script. So somewhere along the way the way JetGroovy runs Groovy scripts was completely changed to use groovyStarter but incorrectly passes all the JDK classes to it, causing the SecurityException. It actually works fine if you remove all the JDK classes from the classpath and run the command.

So the solution that has worked for me today is to downgrade to version 1.0.14201. You can find that version here. Just unzip it and replace the existing plug-in at ~/Library/Application Support/IntelliJIDEA70/Groovy and then you should be able to run Groovy scripts again from within IntelliJ. Of course this also means you cannot upgrade the plugin until GRVY-1088 is fixed.

Posted by sleberkn Feb 20 2008, 04:22:45 PM EST
20080214 Thursday February 14, 2008
Groovier Spring at the Groovy/Grails Experience

I am not very good at the self-promotion thing, mainly because there are so many other people out there way, way smarter than I am. But in this case I'll make a small exception and mention that I'll be speaking next weekend at the Groovy/Grails Experience in Reston, VA giving a presentation called "Groovier Spring" in which I'll try to show how Groovy can make Spring-based applications more dynamic and flexible. Spring solves a bunch of underlying issues with the Java EE platform, for example dependency injection, resource and transaction management using AOP, and allowing applications to be tested more thoroughly and easily.

There is also a podcast on aboutGroovy in which I talk (or blather on, or ramble, or something like that) with Scott Davis about using Groovy together with Spring and talk about my talk, if that makes sense. You can hear it here on aboutGroovy.

Posted by sleberkn Feb 14 2008, 07:06:13 PM EST
20071023 Tuesday October 23, 2007
Validating Domain Objects in Hibernate Part 5: Bypassing Validation To Save "Draft" Objects

This is the fifth in a series of short blogs describing how the Hibernate Validator allows you to define validation rules directly on domain objects. In the fourth article I explained why I don't use several of the standard Hibernate validators. In this article I'll show how to bypass Hibernate validation and when that makes sense.

As indicated by the title of this article, the primary use case I've seen for bypassing standard validation on an object is to allow saving objects in a draft state. For example, suppose you have a lengthy form that a user can fill out, such as a mortgage application or insurance claim, and you want to allow users to save their work as a draft and be able to come back and complete at a later time. In this case, you probably don't want to apply all the validation rules, since it is almost a given that if they haven't finished filling in the form, that it won't pass the validation rules. In this use case bypassing Hibernate validation makes perfect sense. By the way, I am not going to get into the argument of whether storing draft data means that the database must have relaxed constraints, and whether this is good or bad. If you don't relax the database constraints (e.g. allow null values in columns that should be required), then where do you store the draft data? Probably in a separate table that looks almost identical to the "real" table except with all the constraints relaxed (e.g. you might have a loan_applications table as well as a draft_loan_applications table). Assuming, like me, that you don't like that solution and would prefer to save draft objects in the same database table as non-draft objects, read on.

In order to allow the Hibernate event-based validation to be bypassed, you need to create your own validation event listener and provide a way to disable validation temporarily. Since the actual validation logic doesn't change, and the only extra logic we need is to allow clients to turn validation off and then back on, we can extend Hibernate's ValidateEventListener. The following class is all you need (some lengthy JavaDocs have been omitted for brevity):

package com.nearinfinity.common.hibernate.validator.event;

import org.hibernate.event.PreInsertEvent;
import org.hibernate.event.PreUpdateEvent;
import org.hibernate.validator.event.ValidateEventListener;

/**
 * Extension of Hibernate's <code>ValidateEventListener</code> that allows you to bypass the normal validation performed
 * by Hibernate for a specific thread.
 *
 * @author Andrew Avenoso
 * @author Scott Leberknight
 */
public class OptionalValidateEventListener extends ValidateEventListener {

    private static ThreadLocal<Boolean> shouldValidateThreadLocal = new ThreadLocal<Boolean>() {
        @Override
        protected Boolean initialValue() {
            return Boolean.TRUE;
        }
    };

    /**
     * Perform validation before insert, <code>unless</code> {@link #turnValidationOff()} has been called for the
     * currently executing thread.
     *
     * @param event the PreInsertEvent
     * @return Return true if the operation should be vetoed
     */
    @Override
    public boolean onPreInsert(PreInsertEvent event) {
        return isCurrentlyValidating() && super.onPreInsert(event);
    }

    /**
     * Perform validation before update, <code>unless</code> {@link #turnValidationOff()} has been called for the
     * currently executing thread.
     *
     * @param event the PreUpdateEvent
     * @return Return true if the operation should be vetoed
     */
    @Override
    public boolean onPreUpdate(PreUpdateEvent event) {
        return isCurrentlyValidating() && super.onPreUpdate(event);
    }

    /** Call this method to explicitly turn validation on for the currently executing thread. */
    public static void turnValidationOn() {
        OptionalValidateEventListener.shouldValidateThreadLocal.set(Boolean.TRUE);
    }

    /** Call this method to bypass validation for the currently executing thread. */
    public static void turnValidationOff() {
        OptionalValidateEventListener.shouldValidateThreadLocal.set(Boolean.FALSE);
    }

    /** @return <code>true</code> if we need to validate for the current thread */
    public static Boolean isCurrentlyValidating() {
        return OptionalValidateEventListener.shouldValidateThreadLocal.get();
    }
}

The most important things about the above class are:

  • Validation is turned on/off on a per-thread basis using a ThreadLocal variable.
  • If validation is turned off for a specific thread by a client, the client should ensure validation is turned back on after performing persistence operations.

The reason this class uses a ThreadLocal to determine whether to perform validation is because it assumes usage in a multi-threaded environment; for example, you would definitely not want turn turn off validation for all threads in a web application serving lots of concurrent users even for a very short duration! In addition, the reason it is important for clients to reset the validation state for a thread is because the thread might be reused for subsequent client requests, as in many application servers in a JEE environment which pool and reuse threads. (Thanks to Jeff Kunkle for pointing this out.)

The other important thing here has nothing to do with the above code and is instead a configuration issue. If you read my second article in this series you know that Hibernate auto-registers the default ValidateEventListener if it is present in the CLASSPATH, which it will be when you have the Hibernate Validator JAR in your project. So you will need to do two things (refer back to the second article for the configuration details):

  1. Configure the OptionalValidateEventListener for "pre-insert" and "pre-update" events.
  2. Disable automatic registration of the Hibernate ValidateEventListener by setting the hibernate.validator.autoregister_listeners property to "false."

Once that's done you only need to figure out where you need to bypass validation and use code like the following, which is taken from one of our base Spring MVC web controller classes in my current project:

 if (shouldPerformHibernateValidation()) {
     return onSubmitInternal(request, response, command, errors);
 }
 else {
     OptionalValidateEventListener.turnValidationOff();
     try {
         // The following method call would run without any Hibernate validation! 
         return onSubmitInternal(request, response, command, errors);
     }
     finally {
         OptionalValidateEventListener.turnValidationOn();
     }
 }

In the above, the most important thing is that we use a finally block to ensure validation is turned back on regardless of what happened inside the onSubmitInternal() method. We essentially hid this code in a "framework" class so that it is not littered in all the places where we need to bypass validation. The implementation of shouldPerformHibernateValidation() method could be implemented any number of ways, but the point is that you need some way to decide to perform validation or bypass it. Once that decision is made it is easy to turn validation off, execute the code where the bypass occurs, and finally (pun intended) turn validation back on.

In the next and final article in this series, I'll describe how the Hibernate Validator can be integrated into web applications so that validation errors propagate seamlessly from the data access code back up through the web tier and to the end user as nicely formatted error messages.

Posted by sleberkn Oct 23 2007, 10:45:22 PM EDT
20071005 Friday October 05, 2007
Validating Domain Objects in Hibernate Part 4: @NotNull and @NotEmpty

This is the fourth in a series of short blogs describing how the Hibernate Validator allows you to define validation rules directly on domain objects where it belongs. In the third article I showed how to create your own validators. In this article I'll explain the statement I made in the last article that I don't use the @NotNull and @NotEmpty validations in practice, even though at first glance they would seem to be some very useful validators.

First the @NotEmpty validator. Actually this annotation is fine assuming you want to validate "that a String is not empty (not null and length > 0) or that a Collection (or array) is not empty (not null and length > 0)." That is the description in the JavaDoc for the @NotEmpty validator. My only problem with this is that @NotEmpty only applies to strings and collections or arrays. There are lots of times when you want to ensure that dates, numbers, or custom types are required, and @NotEmpty can't help you out. That's pretty much why I don't use it.

Now on to the @NotNull validation annotation. There is a major problem with this validator, which is that it simply doesn't behave the way other validators behave. If you try to save an object having a property annotated with @NotNull, and that property's value is actually null, you would expect to receive an InvalidStateException, which is what happens with other validators. What you actually receive is a PropertyValueException which is the result of Hibernate enforcing a nullability check on the property annotated with @NotNull. I have gone through what happens line-by-line in a debugger and, other than the fact that it is extremely complicated, eventually you arrive at the checkNullability() method in the Nullability class which checks "nullability of the class persister properties" according to the JavaDocs and throws a PropertyValueException with the message "not-null property references a null or transient value." This behavior happens even if the actual column in the database allows nulls!

For example, I have a simple User entity with an active property annotated with @NotNull defined as follows:

 @Type(type = "yes_no")
 @NotNull
 public Boolean getActive() {
     return active;
 }

The user table is defined like this (to show that the active column allows null values):

mysql> desc user;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | bigint(20)   | NO   | PRI | NULL    | auto_increment | 
| version    | bigint(20)   | YES  |     | NULL    |                | 
| active     | char(1)      | YES  |     | NULL    |                | 
| first_name | varchar(255) | YES  |     | NULL    |                | 
| last_name  | varchar(255) | YES  |     | NULL    |                | 
| user_name  | varchar(255) | YES  |     | NULL    |                | 
+------------+--------------+------+-----+---------+----------------+
6 rows in set (0.02 sec)

Finally, I have a test that shows that a PropertyValueException is thrown instead of an InvalidStateException:

@Test(expected = PropertyValueException.class)
public void testNotNullAnnotationPreemptsNormalValidation() {
    // Explicitly set property annotated with @NotNull to null
    user.setActive(null);
    session.save(user);
}

This test passes, meaning that you get a PropertyValueException where with other validators you get an InvalidStateException. For example, here is another test that tests the validation on the username property which is annotated with @Email:

@Test(expected = InvalidStateException.class)
public void testNormalValidationErrorIfNotNullPropertyIsValid() {
    //  Active property is OK here as it gets the default value 'true' in the User class

    // But...make username invalid
    user.setUserName("bob");
    session.save(user);
}

The above test passes meaning that an InvalidStateException was thrown. So, the point of all this long-windedness is that @NotNull behaves differently than other validators and results in a completely different exception being thrown. That is the reason I don't use it and why I created the @Required annotation I showed in the last article.

In the next article, I'll show a technique to bypass validation to allow objects to be saved without the normal validation occurring (and explain a use case where bypassing validation makes sense).

Posted by sleberkn Oct 05 2007, 01:22:34 PM EDT
20070928 Friday September 28, 2007
Validating Domain Objects in Hibernate Part 3: Creating Your Own Validator

This is the third in a series of short blogs describing how the Hibernate Validator allows you to define validation rules directly on domain objects where it belongs. In the second article I showed how to configure the Hibernate Validator and showed event-based and manual validation of domain objects. Here I'll show you how to create your own validators.

The most common use case is validation of individual properties on your domain objects. For example, is a property required; does it need to match a specific pattern; must it have a minimum and maximum length; or must it be a valid credit card number? Hibernate Validator makes creating validators for specific properties easy. In addition to property-specific validators, you can also write class-level validators. For example, maybe you allow certain fields to be blank, but if one of them is entered, then several others are required as well. You annotate property-level validators on properties (i.e. getter methods) and class-level validators on your domain object itself. Here's a short example showing both types of validator:

@Entity
@UserNameConfirmation
public class User extends BaseEntity {
    
    // id, version, etc. are defined in BaseEntity
    private String userName;
    private String firstName;
    private String lastName;
    private String ssn;
    
    @Required
    @Email
    public String getUserName() { return userName; }
    public void setUserName(String userName) { this.userName = userName; }
    
    @Email
    @Transient
    public String getUserNameConfirmation() { return userNameConfirmation; }
    public void setUserNameConfirmation(String userNameConfirmation) { this.userNameConfirmation = userNameConfirmation; }
    
    @Required
    @Length(min = 2, max = 50)
    public String getFirstName () { return firstName; }
    public void setFirstName() { this.firstName = firstName; }

    @Required
    @Length(min = 2, max = 50)
    public String getLastName () { return lastName; }
    public void setLastName() { this.lastName = lastName; }
    
    @Pattern(regex = "[0-9]{3}-[0-9]{2}-[0-9]{4}")
    public String getSsn() { return ssn; }
    public void setSsn(String ssn) { this.ssn = ssn; }
}

In the above example, there is a UserNameConfirmation annotation at the class level. This applies a validator that ensures a user name and a confirmation user name match, but only if the confirmation user name is supplied. There are also several property-level validators being applied: Email, Required, Length, and Pattern. I've also marked the userNameConfirmation property as transient with the @Transient annotation, since this is not actually a persistent property and we want Hibernate to ignore it during persistence operations; it is used only for validation purposes.

So let's actually create a validator now. The @Required validator I've been using in the example code is not one of the Hibernate validators that come out of the box. It has several other ones that are similar (@NotNull and @NotEmpty) but that I don't use in practice - more on why not in the next article though. To create a validator, you only need to do two things:

  1. Define a validation annotation
  2. Implement the validator class

Without further ado, here is the @Required annotation definition:

package com.nearinfinity.hibernate.validator;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import org.hibernate.validator.ValidatorClass;

/**
 * Designates a property that is required to have a value. It cannot be null or empty. The default message is
 * "validator.required" which is assumed to exist in the expected resource bundle
 * ValidatorMessages.properties.
 */
@Documented
@ValidatorClass(RequiredValidator.class)
@Target( { METHOD, FIELD })
@Retention(RUNTIME)
public @interface Required {

    String message() default "{validator.required}";

}

The important things in this code are:

  1. You specify the validator class (the class that performs the actual validation logic) using the ValidatorClass annotation, supplying the validator class implementation as the sole argument.
  2. You need to tell Java where the annotation is permitted via the Target annotation. We'll allow the @Required annotation on methods and fields.
  3. You need to tell Java to retain this annotation at runtime via the @Retention annotation, since Hibernate uses reflection to determine the validators for domain objects.
  4. You specify a message parameter with a default value with value "validator.required" and which is internationalized in the ValidatorMessages.properties resource bundle.

If there are additional parameters you need for your own validator, you can specify them in your annotation. For example, the Hibernate @Length validation annotation specifies a min and a max, like this:

@Documented
@ValidatorClass(LengthValidator.class)
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Length {
    int max() default Integer.MAX_VALUE;

    int min() default 0;

    String message() default "{validator.length}";
}

Now that we've defined the @Required validator annotation, we implement the actual validator class:

public class RequiredValidator implements Validator<Required>, Serializable {

    public void initialize(Required parameters) {
        // nothing to initialize
    }

    /**  @return true if the value is not null or an empty String */
    public boolean isValid(Object value) {
        if (value == null) {
            return false;
        }
        if (value instanceof String) {
            String stringValue = (String) value;
            if (stringValue.trim().length() == 0) {
                return false;
            }
        }
        return true;
    }
}

The important points in the validator implementation class are:

  1. The validator must implement the Hibernate Validator interface, which is parametrized by the validator annotation.
  2. You should also implement Serializable.

The Validator interface is very simple consisting of only two methods: initialize and isValid. The initialize method allows custom initialization, for example you can initialize parameters defined in your validation annotation such as the "min" and "max" in the Hibernate @Length annotation. The isValid method does the real work and validates the object supplied as an argument. That's pretty much it. Implementing class-level validators like the @UserNameConfirmation annotation I showed in an earlier example works exactly the same way. About the only difference is that you probably will restrict the annotation to types, i.e. classes using @Target({ TYPE }). Now, all that's left is to annotate your domain objects!

In the next article I'll explain my earlier statement that I don't use the @NotNull or @NotEmpty annotations in my domain objects.

Posted by sleberkn Sep 28 2007, 12:25:42 AM EDT