Jonas Bonér bio photo

Jonas Bonér

Present.
Entrepreneur.
Hacker.
Public Speaker.
Powder Skier.
Perpetual Learner.
Jazz Fanatic.
Wannabee Musician.

Twitter LinkedIn Github

Jar Jar Links have been part of my Java toolkit ever since we started using it in AspectWerkz a couple of years ago. It is one of these little gems that deserves more attention, and is your best way out of Jar Hell (TM).

Basically it is regular Ant's Jar task on steriods, with a lot of small useful features. I will list some of them here.

Packaging

It works just like the regular Ant Jar task, e.g. you can embed other jars using the zipfileset element, so start using it is a simple matter. Just replace:

<target name="jar" depends="compile">
    <jar jarfile="dist/example.jar">
        <fileset dir="build/main"/>
    </jar>
</target>
with:
<target name="jar" depends="compile">
    <taskdef name="jarjar"
       classname="com.tonicsystems.jarjar.JarJarTask"
       classpath="lib/jarjar.jar"/>
    <jarjar jarfile="dist/example.jar">
        <fileset dir="build/main"/>
    </jarjar>
</target>

But this did not add much value, where it really starts to shine when you start using its feature of prefixing the dependencies.

Prefixing of dependencies

This is the heart of Jar Jar's value proposition. It allows you to prefix dependencies (the actual package names) that are common and might be used by other libraries. For example in AspectWerkz we prefix the ASM library since it is very common and used in f.e. CGLIB, which can create runtime clashes.

...
<!--    define the jarjar task we use to remap ASM -->
<taskdef name="jarjar"
  classname="com.tonicsystems.jarjar.JarJarTask"
  classpath="${basedir}/lib/jarjar-0.3.jar"/>
     <!-- we embed jarjar version of ASM in it -->
     <jarjar destfile="${build.dir}/aw-${version}.jar"
       manifest="${lib.dir}/manifest.mf">
    <fileset dir="${main.classes}">
        <exclude name="**/aspectwerkz/hook/**/*"/>
    </fileset>
    <zipfileset src="${basedir}/lib/asm-2.1.jar"/>
    <rule pattern="org.objectweb.asm.**"
       result="org.codehaus.aspectwerkz.@0"/>
</jarjar>
...

Remove unwanted dependencies

Some days ago I blogged about the problem with Commons Logging and when software depends on it. Well, using Jar Jar, it is actually a simple matter to remove any unwanted dependency altogether. It might not always be the best solution, f.e. you might actually want to have some logging in place, not just use Commons Logging. But is some cases it is very convenient. (Please note that this feature is still experimental.)

Chris Nokleberg has written more about how to use Jar Jar as a Dependency Killer.

Analysis

You can also do some simple, but useful, analysis using Jar Jar. For example finding out which dependencies a library actually has, by either just listing them or use it with graphviz to get a nice graphical view:

Graph of dependencies for a library

It can also find and print out all the strings you are using, good if you want to try to eliminate all your magic values.

Read more about these features in the articles Finding dependencies with JarJar and Dumping strings literals.