Groovy Fun With ObjectRange

Posted on June 25, 2008 by Scott Leberknight

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.

Just How Does Spring Do Its Classpath Component Scanning Magic?

Posted on June 23, 2008 by Scott Leberknight

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.

Creating Executable JARs using the Maven Assembly Plugin

Posted on June 18, 2008 by Scott Leberknight

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.