Saturday, March 23, 2013

JarJar Links

Despite my animadversion for his namesake, JarJar has become my guardian angel in my escape from Java jar hell.

In a nutshell, if you distribute Java libraries to others, (and if you do not work at Google), you cannot expect them to use the same versions of sub-libraries as you do. Hiding those sub-libraries in their own namespace is one way to solve the problem, at the cost of some memory and disk space.

Here is what JarJar does: It uses ASM to walk through .class files, changing their Java package namespace according to a pattern that you supply.

The hard part is to change all the self-references as well. ASM-3 used to have problems with Java generics, so this was only a partial solution to dependency hell. But JarJar uses ASM-4. In fact, it embeds its own copy of ASM-4 so you don't need to worry about finding a compatible version. (ASM-4 works fine with JDK-7.)

You could fairly say that JarJar uses ASM to JarJar ASM into JarJar! Here's how (inside JarJar's own Antfile):

     <target name="jar" depends="compile" description="Create Jar">
          <mkdir dir="dist"/>
          <jarjar jarfile="${jarfile}">
              <fileset dir="build/main"/>
              <zipfileset src="lib/asm-4.0.jar"/>
              <zipfileset src="lib/asm-commons-4.0.jar">
                  <include name="org/objectweb/asm/commons/Remap*.class"/>
                  <include name="org/objectweb/asm/commons/LocalVariablesSorter.class"/>
              <keep pattern="com.tonicsystems.jarjar.JarJarTask"/>
              <rule pattern="com.tonicsystems.jarjar.util.**" result="com.tonicsystems.jarjar.ext_util.@1"/>
              <rule pattern="org.objectweb.asm.**" result="com.tonicsystems.jarjar.asm.@1"/>
                  <attribute name="Main-Class" value="com.tonicsystems.jarjar.Main"/>
                  <attribute name="Implementation-Version" value="${version}"/>

No comments:

Post a Comment