Reflection problem

J

John English

I'm trying to write an application which communicates with a remote
server. Normally an applet is loaded from the server system which
handles all the communication, but in this case I need to use an
application rather than an applet.

The communication uses a class called Message, and Message objects
are sent back and forth using ObjectInputStream and ObjectOutputStream.
My application has a class MessageWrapper which uses a URLClassLoader
to load the Message class from the server and find its constructor and
relevant methods. It then calls the constructor:
private Object obj;
...
obj = cons.newInstance(new Object[] {});
All this works fine.

The problem comes when I try to get the reply message. I do this:
createMessage (in.readObject());
where createMessage creates a MessageWrapper and sets the internal
object "obj" to its parameter. It never gets into createMessage() --
it dies with a ClassNotFound exception, presumably because the
object is one belonging to a class that doesn't exist on my machine.

Can anyone explain how I can get around this?

-----------------------------------------------------------------
John English | mailto:[email protected]
Senior Lecturer | http://www.it.bton.ac.uk/staff/je
Dept. of Computing | ** NON-PROFIT CD FOR CS STUDENTS **
University of Brighton | -- see http://burks.bton.ac.uk
-----------------------------------------------------------------
 
J

John English

John said:
I'm trying to write an application which communicates with a remote
server. Normally an applet is loaded from the server system which
handles all the communication, but in this case I need to use an
application rather than an applet.

Panic over -- problem solved. For the benefit of others who
might find themselves in this situation, I'll explain...
The communication uses a class called Message, and Message objects
are sent back and forth using ObjectInputStream and ObjectOutputStream.
My application has a class MessageWrapper which uses a URLClassLoader
to load the Message class from the server and find its constructor and
relevant methods. It then calls the constructor:
private Object obj;
...
obj = cons.newInstance(new Object[] {});
All this works fine.

The problem comes when I try to get the reply message. I do this:
createMessage (in.readObject());
where createMessage creates a MessageWrapper and sets the internal
object "obj" to its parameter. It never gets into createMessage() --
it dies with a ClassNotFound exception, presumably because the
object is one belonging to a class that doesn't exist on my machine.

This is very poorly documented -- I searched Sun's website
and also the big wide world without turning up anything
useful. Finding the answer involved quite a lot of detailed
experimentation. The answer I found (maybe not the only one,
who knows) was to derive from ObjectInputStream and override
resolveClass(), as follows:
protected Class resolveClass (ObjectStreamClass osc) {
if
(osc.toString().equals(ObjectStreamClass.lookup(myClassObject).toString()))
{
return myClassObject;
else {
return super.resolveClass(osc);
}
}

Note the conversion to String of the ObjectStreamClass; I found
that using a.equals(b) always yields false for ObjectStreamClasses.
Don't ask me why, but the string representation includes the class
name and the corresponding magic number, so that's good enough for
me; and besides, it works.

Another interesting fact: my MessageWrapper class was originally
called Message, the same name as the class I was downloading.
Having downloaded the class and got a Class object, I tried
calling its constructor and got a StackOverflowError. It seems
that the constructor that I got from the Class object was a
constructor for any old class called Message that it could
find, not just the class encapsulated in the Class object.
Result was, as soon as I called the constructor, it recursed
up its own backside at several gigahertz and blew the stack
to pieces.

So, for anyone else who wants to play the same sort of games,
I hope that this advice about using reflection and ObjectInputStream
will prove useful. As for me, my black magic tolerance has reached
saturation point, and I need a drink, a bath, and a good long sleep.

Good night all... :)

-----------------------------------------------------------------
John English | mailto:[email protected]
Senior Lecturer | http://www.it.bton.ac.uk/staff/je
Dept. of Computing | ** NON-PROFIT CD FOR CS STUDENTS **
University of Brighton | -- see http://burks.bton.ac.uk
-----------------------------------------------------------------
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top