Saturday, March 23, 2013

JarJar Links


  • http://priyanka-tyagi.blogspot.com/2013/03/dealing-with-java-hell-using-jarjar.html
  • https://code.google.com/p/jarjar/
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"/>
              </zipfileset>
              <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"/>
              <manifest>
                  <attribute name="Main-Class" value="com.tonicsystems.jarjar.Main"/>
                  <attribute name="Implementation-Version" value="${version}"/>
              </manifest>
          </jarjar>
      </target>

No comments:

Post a Comment