Re: RMI-USERS Digest - 6 Nov 2008 to 18 Nov 2008 (#2008-39)

Gregg Wonderly <[email protected]> Thu, 20 Nov 2008 17:55:01 -0600
Newsgroups gmane.comp.java.sun.rmi
Message-ID <[email protected]>
Gregg Wonderly wrote:
> Esmond Pitt FACS wrote:
>> 1. RE: ClassCastException with inner-class application
>>
>>> java.lang.ClassCastException: cannot assign instance of $Proxy2 to field
>>
>> There are two causes for that.
>>
>> (1) the interface implemented by the remote object doesn't extend Remote
>> (2) the interface implemented by the remote object isn't the same as the
>> interface
>> expected by the client, i.e. you have copied the interface into another
>> package.
> 
> Or it was loaded by different classloaders because a context ClassLoader 
> loaded the class which was downloaded and the app classloader loaded the 
> class which it is being cast with.

You should print out the getClassLoader() value for both the object and the cast 
class to see that they are being resolved where you want them to be.  Usually, I 
have problems like this when I have a swing event thread doing something for me 
that results in class loading and I forgot to set the context class loader to 
the classloader of the remote object.  I have a version of SwingWorker that 
includes setting the context classloader to getClass().getClassLoader() for the 
current instance so that my downloaded client-GUI code never has this step in it 
explicitly, unless I spawn a non-swing background thread to do something.

Also, the PreferredClassLoader in Jini helps solve this problem (but its focus 
is really more on versioning) by letting you include a PREFERRED.LIST file in 
the manifest tree that indicates which classes/packages are preferred by the jar 
so that they are always resolved to the jar.  Interfaces and abstract classes 
shared between the client and server are never preferred, typically.  Thus, you 
always prefer everything used internally, and never things visible externally. 
By not preferring the class you are casting to, it would be loaded from the 
parent class loader.

The JERI stack uses PreferredClassLoader internally, at the moment of 
unmarshalling automatically, and sets the ContextClassLoader of the calling 
thread to this classloader.

Pretty handy stuff...

Gregg Wonderly

===========================================================================
To unsubscribe, send email to [email protected] and include in the body
of the message "signoff RMI-USERS".  For general help, send email to
[email protected] and include in the body of the message "help".

For a list of frequently asked RMI questions please refer to:
http://java.sun.com/j2se/1.3/docs/guide/rmi/faq.html

To view past RMI-USERS postings, please see:
http://archives.java.sun.com/archives/rmi-users.html