This page contains an archived post to the Design Forum (formerly called the Flexible Java Forum) made prior to February 25, 2002.
If you wish to participate in discussions, please visit the new
Artima Forums.
Message:
Two Rodents are NOT Better than One
Posted by Bill Venners on 22 Dec 1998, 8:12 PM
> My applet is in a jar file, which includes the Rodent class. > The applet dynamically loads the Mouse class from another > directory (which includes the Rodent class), but fails to > cast the retrieved class to the Rodent class. > As Yoda said to Luke Skywalker, "That is why you fail." At least I think that's why you are failing. Here's my guess at the problem you are having: The trouble is that you are loading in Rodent twice, once into the applet class loader's name space (the one in the JAR file) and once into the RodentClassLoader's name space, by getting it from, as you put it, "another directory." Even assuming both of these Rodent's are identical, they will be parsed into the method area twice and two java.lang.Class objects will be created to represent them. This causes you to encounter one of the lesser known aspects of Java's object model: A cast or instanceof succeeds only if the is-a relationship holds in the name space of the class whose code is asking for the cast or instanceof. In your case, the Mouse is a subclass of the Rodent loaded by RodentClassLoader, but isn't a subclass of the Rodent loaded by the applet class loader, even though both Rodent's are identical. Since your applet is the class which is asking for the cast, the JVM checks to see if Mouse is an instance of the Rodent loaded by the applet class loader, which it isn't. Thus, you get a ClassCastException. Here's how to solve the problem: You'll need to edit the RodentClassLoader to first ask not the primordial loader for the type, but the applet class loader. If the applet class loader can't find the type, then go ahead and look in that "other directory." How do you get at the applet class loader? Before you instantiate RodentClassLoader in your applet, do something like: Class myClass = getClass(); ClassLoader appletClassLoader = myClass.getClassLoader();
Then, you'll have to make RodentClassLoader accept a reference to a class loader in its constructor so you can pass in the reference to the applet class loader like this: RodentClassLoader rcl = new RodentClassLoader( appletClassLoader, "that/other/directory");
To ask the applet class loader for a type from the RodentClassLoader's loadClass() method, just invoke loadClass() on the reference to the applet class loader, passing along the fully qualified name of the type to load. If you want to get Java 2ish, you can specify the applet class loader as a "parent class loader" and simply override findLocalClass() with the code that looks in the "other directory." Check the Java 2 class loader documentation for details on this approach. Let us know how it goes. bv
Replies:
- Thank you Patrik Mihailescu 23 Dec 1998, 3:23 PM
(1)
- afsa asf November 15, 2000 at 1:21 PM
(0)
|