2

searching for a long time, but didn't find any answer on that one:

I have a server and I have a client. The server should receive an object via ObjectInputStream and ObjectOutputStream. That already works for any class, known on the server. Now I want to send an Object of a class the server doesn't know. He only knows the interface of that class. And that obviously fails...

How can I avoid the ClassNotFoundException? I thought interfaces were the solution. I only want to access the functions I know by the interface, but Java wants to have the class anyway.

Thank you.

2
  • Does the interface exist on the server? Commented Feb 26, 2013 at 13:19
  • Yes, the interface is on the server. Commented Feb 26, 2013 at 13:22

3 Answers 3

3

There is no way. To be able to execute a method on an object, you need to have the byte-code of the concrete class of the object. Its interface isn't sufficient.

Sign up to request clarification or add additional context in comments.

7 Comments

Well, that's not what I liked to hear ;-)
So then I'll send the .class to the server and load it, before receiving my object.
@JBNizet "There is no way" does not sound like an answer for me. Actually there are some ways, i.e. to send .class file before sending the object.
@MatthiasNiemann You need to make server to receive .class files form client, create ClassLoader instance that is able to load these classes and then somehow tell to ObjectInputStream to use this classloader which is not a trivial task, because ObjectInputStream is a piece of ... em ... strange design. But though, "there is no way" does not sound as correct answer for me.
What I mean is that "there is no way" to load an object without having its bytecode. Of course, you could design a system where a class's bytecode is sent before the object, and a specific classloader is used in order to load the class and instantiate the object. But that is an very hard task. Just sending the class of the object is not sufficient. You also need to send its dependencies, recursively. And you'd better not do that for every object sent. So it's very, very, very far from trivial, and I wouldn't advise going this way.
|
0

Object of some class may exist in JVM only if JVM has this class loaded. Probably instead of sending objects of unknown type, you better send some well-known data structure that describes the object, i.e. HashMap. So, instead of doing:

MySecretClass o = new MySecretClass ();
o.setFoo ("Hello, World!");
o.setBar (123);
send (o);

you do the following:

Map o = new HashMap ();
o.put ("foo", "Hello, World!");
o.put ("bar", 123);
send (o);

7 Comments

I already thought of that - but I want to access a method in that object, not only the data in it.
@MatthiasNiemann If you need methods, then you definitely need .class file of the class to be available on server, because logic of the methods is in classes, not in objects. Consider sending .class files from client to server.
There are other ways. For example you may send object using RMI instead of serialization. In this case, when server will call method on received object, the call will be marshalled to the client, client will execute the method and will send result back to the server.
I believe RMI only defines a different channel for passed objects. And the issue remains the same. It's a pretty interesting question I have been thinking about for while though.
@MarianP RMI passes only object identity (i.e. reference), not object itself.
|
0

You need the particular class' bytecode on server, so it won't work as you imagined.

You could send a proxy object of a class that would be known to both the client and the server. The proxy would contain the object of the class unknown to the server and its class would be stored in the proxy as a byte array. The proxy class would be Externalizable and would use Classloader.defineClass to dynamically create the unknown class in the server JVM when the proxy object is deserialized (using the byte array with class definition passed from the client). It won't be exactly fast, but could be optimized, like do not send and load definition of a class twice etc.

In case you need to call the interface specific methods directly on the object passed from client, make the proxy implement your interface and use dynamic proxy pattern on the proxy object (java.lang.reflect.Proxy/InvocationHandler) to pass calls to the proxied object of the previously unknown class.

It's rather complicated, but could be done like this, I believe.

1 Comment

After some discussion under a different answer, it's worth noting that one would need to send the class' dependencies too.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.