6
2006
Doing Package Name Kung-Fu with JarJarLinks
If you’ve ever had issues with conflicting versions of the same jar file, you really need to take a look at JarJarLinks . JarJarLinks is an Ant task that lets you repackage jar files into your own package scheme by doing neato bytecode kungfu.
So you can do stuff like this to repackage commons-kungfu.jar into your own package structure:
<jarjar jarfile="myapp.jar">
<fileset dir="build/classes"/>
<zipfileset src="lib/commons-kungfu.jar"/>
<rule pattern="org.apache.commons.kungfu.**" result="au.com.bytecode.commons.kungfu.@1"/>
</jarjar>
In the sample above (stolen from the manual), you simply use the jarjar task (which descends the standard jar task, and offers all the same config switches) to repackage the classes from commons-kungfu.jar into myapp.jar. Jarjar rips out the classes, changes the package naming to whatever makes sense for you, changes any references in your code to the new name, then adds the modded classes to your target jar. So, for instance, Jarjar does the work of changing all your references to org.apache.commons.kungfu to, say, au.com.bytecode.commons.kungfu and repackages the changed classes inside your own jar. You then no longer need to distribute commons-kungfu.jar with your app – the changed classes end up in your app’s jar file.
Here’s two killer scenarios…
- Scenario one is when you don’t want to ship external jars (commons-kungfu.jar) with your standalone app.
- Scenario two is when you want to bundle commons-kungfu.jar with your webapp, but your appserver has an old version of commons-kungfu.jar in its own root classloader. Use jarjar to package it into your own war file under a different package name and you’re good to go.
I’ve recently used it to great success where I wanted to deploy a particular jar file to /lib/ext on Websphere, but didn’t want to force everyone else on the appserver to use that particular version of the jar. Repackaged the jar into my own naming structure and I was good to go.
JarJar is even smart about embedded strings in your jar files. So if you do a Class.forName("org.apache.commons.kungfu.FactoryImpl") then that string will be successfully changed to the new package name too.
Many props to the guys at Tonic Systems. Really slick piece of work!
3 Comments + Add Comment
Leave a comment
Glen Smith
Archives
- April 2012
- March 2012
- January 2012
- November 2011
- October 2011
- September 2011
- August 2011
- July 2011
- June 2011
- April 2011
- March 2011
- January 2011
- November 2010
- October 2010
- September 2010
- August 2010
- July 2010
- June 2010
- May 2010
- April 2010
- February 2010
- January 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
- August 2006
- July 2006
- June 2006
- May 2006
- April 2006
- March 2006
- February 2006
- January 2006
- December 2005
- November 2005
- October 2005
- September 2005
- August 2005
- July 2005
- June 2005
- May 2005
- April 2005
- March 2005
- February 2005
- January 2005
- December 2004
- November 2004
- October 2004
- September 2004
- August 2004
- July 2004
- June 2004
- May 2004
- March 2004
- February 2004
- January 2004
- December 2003
- November 2003
- October 2003
- September 2003

An article by Glen





Hello
About the second scenario : you can also force the classloader to load the version of common-kungfu shipped in the webapp. In the websphere admin console, you need to set the property “classloader preference” to “PARENT_LAST” (default value is “PARENT_FIRST”).
Hope it helps
Great point, Victor! You’d need to do it for every webapp running on that server I’d assume. Or is there a way to change that setting globally? So all webapps default to PARENT_LAST (including newly deployed ones)?
I am not sure you can change the default settings… However, you can use jacl scripts to automatically deploy your war and set up the classloaders.
Alex