views:

73

answers:

4

I have a library that writes data in either a text or binary format. It has the following three components:

  1. common data structures
  2. text writer (depends on 1)
  3. binary writer (depends on 1)

The obvious way to distribute this is as 3 .jar files, so that users can include only what they need.

However, the "common data structures" component is really just two small classes so I'm considering creating only two .jar files and including the common .class files in both.

My question: What are the potential problems with doing this?

+1  A: 

If you release a new version of your library, a user who uses both libraries (one old one new) could get runtime exceptions, when the new library gets a class from 1 from the old library (or vice versa if it is not backwards compatible). The easiest would be, to release all in one jar, so you would not get this version issue.

Dominik
A: 

Potential problems is that in the future data structure versions between these two jar files could get inconsistent (say because bug fixing or a minor release). In this case you could get ClassDefNotFoundException if you need to include both jars into an application. I would recommend either to divide it in three jar files or just one bigger one.

Marcos Carceles
+1  A: 

The potential version mismatch others mentioned is actually one case of a larger set of classloading problems you might face if you deploy the same class(es) in different jars.

Classloading bugs are most likely to bite you in an application server / EJB container or similar setup, where there are multiple components / apps loaded by a hierarchy of classloaders. However, if the same class is loaded by two different classloaders, these are seen as totally distinct classes by the JVM! Which may result in different runtime errors like LinkageError (e.g. if two different versions of the same class definition collide - as described in other answers), ClassCastException (if a cast is attempted between two class definitions loaded by different classloaders) etc. Believe me, classloading hell is a place you don't want to see.

I would put the whole library into a single jar to minimize that risk.

Péter Török
A: 

I recommend using JarJar which is a library for packaging a number of jar files in a single jar file.

There is an Ant task for integrating into your build and your build environment can therefore just keep the raw jars and you can just have a simple deployment (but remember to include the license.txt files from the various libraries with your distribution).

Chris