[ajug-members] FW: [Fwd: multiple jar versionsfor one application]
Eugene Thompson
vttoonses at gmail.com
Thu May 1 20:05:08 EDT 2008
Chris,
I think I'm confused as to what problem you are trying to solve. From
your original post, it seemed as if you wanted polymorphic behavior
out of some classes, but I could be wrong. Are you truly looking to
use two different versions of the same class (from different jar
files) who's source you don't have access to? Or are you implementing
these classes and you want two different behaviors based on which type
is instantiated? If it is the former, then I think Jed gave you the
answer you were looking for (and a lot of us have some crow to eat),
but if it is the latter, then there are much simpler methods for
achieving this than involving class loaders (explicitly).
Gene
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
>
More information about the ajug-members
mailing list