commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Craig McClanahan <>
Subject Re: AW: AW: [proposal] avoiding jar version nightmares
Date Mon, 20 Dec 2004 00:10:42 GMT
The ability to declare your own versioning information, and that of
your dependencies, in a MANIFEST.MF file already exists:

Two existing use cases for this information are applets and servlet
containers, where the container should examine the manifest of the
applet itself (or the WAR in the case of a webapp) and reject
execution if the specified versions of the declared dependencies are
not present.  But nothing stops a container from doing more with this
info (see below for one idea).

What's missing today at the *language* level is the ability to load
incompatible versions into the same class loader.  That would take
language and JVM architecture changes -- if that's important to you,
go find the threads on ServerSide or JavaLobby about providing
feedback to the requirements for Mustang (JDK 1.6), since that's the
earliest time we could actually get it into the language itself.

In the mean time, nothing stops a servlet container provider from
assembling dynamically an appropriate parent class loader that
contains just the specified dependencies (instead of, or in addition
to, the kind of thing that Tomcat does with its "shared" and "common"
class loaders).  That way, one could provide webapp A with version 1
of the library, and webapp B with version 2 of the same library, which
is pretty much equivalent to what you describe for .NET.  Seems like a
good RFE for Tomcat ...

However, this won't solve the "two incompatible versions in the same
webapp" use case -- for that, you'll still need to use child class
loaders.  It sounds like this would also be true in the .NET


On Sun, 19 Dec 2004 18:37:43 -0500, Matt Sgarlata
<> wrote:
> Craig McClanahan wrote:
> > On Fri, 17 Dec 2004 19:10:32 -0500, Matt Sgarlata
> > <> wrote:
> >>How do we go about petitioning Sun for something like this?
> >
> >
> > A while back now (while the details for Tiger were being planned), I
> > happened to be in a meeting with Graham Hamilton (who basically owns
> > the direction that J2SE is going from a Sun perspective), talking
> > about the very issue of class loaders and the contortions that you
> > have to go through in order to implement things like webapp reloading.
> >  I asked him for a Christmas present to all Java developers -- add
> > something like ClassLoader.unloadClass() or ClassLoader.replaceClass()
> > to deal with things like this.  He said "hmm ... that's a hard
> > problem" and proceeded to describe several of the places where
> > implementing this would be extremely difficult (and/or would have
> > nasty performance impacts) in the current architecture of JVMs.
> Well what about introducing the versioned library approach that is done
> in .NET?  I'm not familiar with the details myself, but Chris Lambrou
> wrote earlier:
> The .NET equivalent of a jar file is called an assembly. For libraries,
> this is basically a DLL. Every time the code is compiled, the DLL is
> automatically allocated a unique version number. When you compile your
> code that refers to code in a library assembly, your assembly has an
> explicit dependency on that library assembly. At runtime, when your code
> tries to invoke the library code, an exception will be raised if the
> exact version of the library assembly is not available.
> It would appear that if there are bug fixes or other improvements to the
> library, and a recompiled assembly DLL is substituted for the one you
> originally compiled against, then your code will break. At runtime, your
> code will fail to link to the library code, since the version number no
> longer matches. Obviously, a maintenance release of a library component
> shouldn't require a recompilation and redeployment of all software that
> uses the library, so .NET provides a mechanism for you to explicitly
> define a version number. This allows you to provide updated library
> components to users without requiring them to recompile. However, this
> only works if you don't break backwards compatibility.
> If you break backwards compatibility in a library, then you have to
> change the version number. However, .NET still allows you to deploy
> different, incompatible versions of the same DLL. When you deploy the
> application, your installer has to register both versions of the DLL
> with the GAC - the Global Assembly Cache. In this way, if you have a
> complex application that contains two components that rely on
> incompatible versions of the same library DLL, the VM instantiates two
> separate versions of the library DLL, and links the two components to
> the appropriate instance.
> One possible Java analogy to this would be to bundle all code inside jar
> archives. Each jar contains dependency information, perhaps stored in
> the manifest, or some other meta-file, that describes the jar's own name
> and version number, and a list of the names and version numbers of its
> dependencies. A suitable class loader can then use this meta information
> to stitch the classes together appropriately. Actually, my knowledge of
> java class loaders isn't  sufficient for me to assert that this solution
> would definitely work, but it's a start, and I hope all of this serves
> to illustrate how .NET allows multiple versions of the same library to
> coexist.
> > Regarding the original use case in this thread (an app that wants to
> > use two modules that have conflicting versions of common
> > dependencies), about the best you can do right now is to have your
> > application create its own class loaders for the modules involved, and
> > set up their classpaths to pick up their own versions of the
> > dependencies.  That is essentially what a servlet container does
> > (creates a class loader for each webapp) to maintain separation, and
> > allows each webapp to load its own version of a common dependency JAR
> > from its own "class path" ... the /WEB-INF/classes and /WEB-INF/lib
> > directories of that app.
> >
> > Craig
> ---------------------------------------------------------------------
> To unsubscribe, e-mail:
> For additional commands, e-mail:

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message