[ajug-members] FW: [Fwd: multiple jar versionsfor one application]

Les Hazlewood les at hazlewood.com
Thu May 1 20:44:39 EDT 2008


Jed, we've been saying all along that it can't be done _in the same
classloader_.  It is possible to do via different class loaders, although,
unless Chris is developing or working with framework internals, I doubt this
is what he wants to do.  I'm just repeating myself (twice!) ;)
Multiple classloaders are _rarely_ ever used by application developers.  I'm
not saying it doesn't happen, but if you do need to go through that
exercise, it should be noted as a red flag that something isn't right, and
that further inspection into alternatives are a good idea before you go down
that road.  Unfortunately, Chris didn't provide much of a back story as to
what his restrictions are or what exactly he's trying to achieve, so we
couldn't go beyond telling him the basics: that its not possible unless you
(or a framework you use) utilize(s) different classloaders.
Cheers,

Les

On Thu, May 1, 2008 at 4:44 PM, Chris Abney <Chris.Abney at theice.com> wrote:

> Here is a great answer from Jed Casper.  Thnaks Jed
>
> Chris Abney
>
> BTW. If you don't have that book, here is the excerpt from the web:
> http://www.informit.com/articles/article.aspx?p=1187967
>
> -----Original Message-----
> From: Jed [mailto:jcasper at ga-1.com]
> Sent: Thursday, May 01, 2008 4:31 PM
> To: Chris Abney
> Subject: [Fwd: multiple jar versionsfor one application]
>
> Chris,
>
> Everyone keeps responding that you can't do it, but I disagree.  That is
> to say that I don't think you have to change the package or class name
> or anything about the code that you are using, and that may not be under
> your control to make changes to at the source code level.
>
> For instance, when I deploy webapps, I have the exact same code in the
> exact same named jar file go into the WEB-INF/lib folder for each one.
> This code has a static initializer to create a singleton instance of a
> class.  When the class is loaded the static initializer creates the
> singleton and each webapp has it's own singleton instance, even though
> all webapps are running in a single JVM instance, because the code for
> each webapp is loaded with a different classloader.  To match your
> problem description further, the code for the singleton objects could be
> different (like different versions of the same thing) and you can see
> that each webapp has it's own instance and it's own version of the code,
> even though the jar file may be named the same and the name of the class
> is exactly the same.
>
> Here is an excerpt from Core Java book .... ISBN is 0-13-111826-9
>
> "It may surprise you, however, that you can have two classes in the same
> virtual machine that have the same class and package name. A class is
> determined by its full name and the class loader. This technique is
> useful for loading code from multiple sources. For example, a browser
> uses separate instances of the applet class loader class for each web
> page. This allows the virtual machine to separate classes from different
> web pages, no matter what they are named."
>
> So, all you have to do is load each class with it's own classloader.
>
> ClassLoader loader = new MyClassLoader(); Class c =
> loader.loadClass(name);
>
> where MyClassLoader overrides findClass() to get the bytes for the class
> file and pass them to defineClass().
>
> Since the loadClass method will delegate to the parent class loader
> first, you will need to make sure it cannot find one of your conflicting
> classes.  Take it off the classpath.  Now your classloader will load and
> define one of the conflicting classes and it will essentially become a
> separate type than the one loaded by the system class loader....all
> running in a single JVM.  You can operate on your loaded class via
> reflection on the Class object. The classloader essentially acts as a
> another level of namespace scope.
>
> You might consider using two classloaders for each or your conflicting
> classes (and everything they reference); two separate "class"-paths,
> that your classloaders use, where everthing is the same except for the
> conflicting classes will have different code.
>
> public class myClass {  //Put myClass on the classpath
> :
>  public void doIt() {
>    ClassLoader loader = new MyClassLoaderDaddyBee(); //loads classes
> from path A - not on formal classpath
>    Class daddyBee =
> loader.loadClass(org.chrisabney.functors.WorkerBee);
>
>    ClassLoader loader2 = new MyClassLoaderSonBee();  //load classes
> from path B - not on formal classpath
>    Class sonBee = loader.loadClass(org.chrisabney.functors.WorkerBee);
>
>    Method daddyMethod = daddyBee.getMethod("doIt", null);
>    Method sonMethod = sonBee.getMethod("doIt", null);
>
>    daddyMethod.invoke(daddyBee.newInstance(), null); //The old boring
> way
>    sonMethod.invoke(sonBee.newInstance(), null); //The new wacky way
>  }
> }
>
> Good luck.  With everyone saying it can't be done, maybe I'm the one
> who's wrong ; )
>
> Jed Casper
>
>
>
> _______________________________________________
> ajug-members mailing list
> ajug-members at ajug.org
> http://www.ajug.org/mailman/listinfo/ajug-members
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.ajug.org/pipermail/ajug-members/attachments/20080501/b0ea3a42/attachment-0001.html 


More information about the ajug-members mailing list