Java’s classpath is a powerful concept – when used appropriate. As your project grows larger in terms of code and people, it gets harder to ensure that your classpath is correct. A great danger arises from JAR files containing different versions of the same resource. You might end up running different code than you think, leading to strange effects. If you build your classpath using wildcards, you can’t even control the order your JAR files are loaded.
Managing dependencies
To avoid the issues mentioned above, you need to manage your project dependencies. It’s a common practice to implement the build process of the project using maven or ant ivy. Both tools provide dependency mangement by declaration. But at a high cost. Especially maven has received some malice lately, criticizing its steep learning curve and complexity.
Scratching the biggest itch
We decided to try a different approach to dependency management, tackling only our biggest concern: The duplication of classpath resources. We take care of the scope of a third-party library, put required JARs in the repository (to us, third party binary artifacts are part of the project source) and update manually. The one thing we cannot assure manually is that every resource is unique. Sometimes, the same class is included in different JARs, as it seems to be common practice among java web frameworks.
Ant to the rescue
Thus, I wrote a custom ant task that, given the classpath, checks for duplicate entries. If it finds one, it lists the culprits and optionally aborts the build process. Included in our continuous integration system, it gets run every time somebody performs a change. You can’t forget to delete an old version of a library or check in the same library twice without breaking the build now.
Our ClasspathCollisionCheckTask
I provide this task here, without any warranty. The source code is included in the JAR alongside the classes, if you want to know what it does exactly.
Assuming you already know how to use custom tasks within an ant build script, here’s only a short usage description.
Import the custom task:
<taskdef
name="check.collision"
classname="com.schneide.internal.anttask.ClasspathCollisionCheckTask"
classpath="${customtasks.library.directory}/schneidetasks.jar"
/>
Next, use it on your classpath:
<check.collision verbose="true" failOnCollision="true">
<path>
<fileset dir="${classpath.library.directory}">
<include name="**/*.jar"/>
</fileset>
<fileset dir="${internal.library.directory}">
<include name="**/*.jar"/>
</fileset>
</path>
</check.collision>
The task scans the whole path you give it and reports any collision it detects. You will see the warnings in your build log.
If the failOnCollision parameter is set to true (optional, defaults to false), the build will abort after a collision. If you want to have debug information, set the verbose parameter to true (optional, defaults to false).
Conclusion
If you manage your project dependencies manually, you might find our custom ant task useful. If you use maven or ant ivy, you already have this functionality in your build process.
Feedback
I’m very interested in hearing your opinion on the task or about your way of handling dependencies. Leave us a comment.






We started this blog in February 2007. Soon afterwards, it was nearly dead, as no new articles were written. Why? We would have answered to “be under pressure” and “have more relevant things to do” or simply “have no idea about what to write”. The truth is that we didn’t regard this blog as being important to us. We didn’t allocate any ressources, be it time, topics or attention to it. Seeming unimportant is a sure death cause for any business resource in any mindful managed company.





