I am trying to send a class over a TCP connection using java. When the client receives the class it should invoke the methods of that class and return the result to the server.
I have serialized the class to a byte array to send to the client, but I don't know with it once the client receives it.
Thank you.
Your question is a bit ambiguous. Are you sending a *.class file or an instance of the class? I'll bet that you actually mean an instance of the class since you literally said that you want to send it back. This makes only sense if it were an instance. The other side should then have the class file in its classpath as well. Then you can just import the class and cast to the desired class on readObject(). Finally you'll be able to invoke methods on it according the class' contract.
See also:
Basic Serialization tutorial
Advanced Serialization tutorial
If you're actually sending a *.class file, using a ClassLoader to load it would indeed be the answer.
You probably need to use a ClassLoader.
If possible for you, you may want to look at RMI where clients can provide classes for the server to invoke.
Related
i am working on a chat program.
[JAVA] [Without RMI, just Sockets] [Command example: 'sentToMike', 'Disconnect', 'Login', etc]
How do i send a "command" Object through Sockets to be excecuted on the server directly?
I want to send all kind of messages(Strings, Audio, Video), and all kind of Command objects to many clients, any of them. I know there exist ObjectInput/Output objects and all of that. My problem is trying to get a polymorphic solution.
For example i want to create a IMessage interface with a method signature "execute()". Then i would create a AudioMessage, TextMessage, etc that implements the IMessage. The problem is that at some point i need to share the server code with the client and viceversa in order Server and client know all the objects involved in every excecute method. And worst of all is that if i send an IMessage, the server would't know what specific type the message is, so i dont know to what kind cast the Object. The same would happen when i send the Command back to the client.
I can work a solution with simple text strings "commands" and a big and ugly switch in the server(and in the client by the way), but i believe that is not elegant, i would need to create a wrapper class with the string command plus the object of the kind i want to send plus the string with the type of object been sent(Message[String type; String command; IMessage->AudioMessage ]), this wont be polymorphic since i will need to use the switch to ask the type of the object and then cast it to AudioMessage for example. Furthermore i would need to share a lot of code between server and client and i dont know if that would be ok.
Any advice will be very very welcome, maybe i need a design pattern, an architecture pattern, i have no clue.
There are security reason to not allow just any code to run on server!
But if you are willing to expose your server (and client) to unknown code, then you need to also serve classes bytecode, and have classloaders to enable instanciating classes' types you expect the other end to accept. Your protocol would have to send the full classname and locations (if not inlining the bytecode) of the alien class (and all its dependencies not found in parent classloader), for the purpose of hoping to call any method of such object.
(FYI, that just reinventing RMI).
If you don't have to call anything on this object (it's not your case, I know, but I musy say it), then it is passive and there is really no point in transporting it as an object instance.
I am sending some packets through kryonet that simply hold an "Entity" variable. I created the entity class myself. The thing is that when registering the entity class, the class file on the server and the client are not exactly the same.
On the client side, I did not include some methods because they rely on accessing variable that are only server side and I completely removed all constructors because the client will not be the one creating entities, the server will. On the server wide I left out the render method since the server will not be rendering.
Does it really matter what methods and constructors are there? Does kryonet only look to see if the variables are the same (cause they are)? Thanks!
By the way, if you were wondering, Entity is an abstract method and therefore when I create new types of entities like "Player" for example, they extend it and add even more methods and variable. I hope that is alright for sending those in a packet too.
I am not sure what you are asking but as far as I understand I will try my best to answer your question.
So I think what you are trying to do is you have a base class called Entity and you extend it to different classes. You implement some methods in class which will be sent to client and some which will be sent to server.
So as you asked does it matter what methods and constructor are there, the answer is NO. Till the time you have an empty Constructor (required by Kryo serializer) kryonet is fine with whatever constructor you have. Just you need to make sure you have an empty constructor. I have many classes in kryonet with more than 2 constructors and they work perfectly fine.
A tip, since you are sending data on network, if I was you I would have removed all the data variables which will not be used in client and abstracted out the classes even more.
Also why are you sending methods in classes? Just curious. I think you should have methods in server and client and you should take the data out of the packet (classes) and then send it to the method in your server or client.
If anything is not clear let me know.
I'm trying to make a server that receives an object that implements an interface X sent by a Client through the ObjectInputStream ().
Better Explain:
I want to make the Server receives the Object through an interface without actually having the Class on Server side.
Because of ObjectInputStream () deserialize the Object, the class must necessarily exist on the server side, if does not, occur ClassNotFoundException ().
Is there any other way to pass an Object through a Socket without necessarily having the Class of him on the other side? I'm searching different ways that do the same ObjectInputStream, but without having the Class on Server side. If thre's no way of do that, I will must upload the Class all the time on the Server, so the ObjectInputStream can deserialize and dont throws ClassNotFoundException.
Thanks.
If you don't want to instantiate the object, you can keep it in a byte[] buffer. To instantiate it, you need to do it like RMI: provide a remote class loader by the sender.
But typically solutions using a different serialisation mechanism are better for that case. Think Protobuf, JSON or similiar.
I have a java class that contain a method with some logic control . This class is avaible as output via a webservice method to a java swing client .
My question sounds crazy but is it possible to marshal/unmarshal the method to make it available to the client when he generate the class from the wsdl file ?
Thanks.
ps:I'm using Metro/jax-ws and glassfish 3.1.1.
You mean so you can send some logic down to the client to be executed there?
I'm afraid the answer is no - this is not how web services work.
All the logic is performed on the server side.
Why do you wish to do this?
Why not provide this class (your VO) to the client so both the server and client are marshalling/unmarshalling the same class? Then both can use the your method...
Marshalling" refers to the process of converting the data or the objects into a byte-stream, and "unmarshalling" is the reverse process of converting the byte-stream back into their original data or object.
The conversion is achieved through "serialization".
The purpose of the "marshalling/unmarshalling" process is to transfer data between the RMI systems.
For more http://ws.apache.org/old/jaxme/manual/ch02s02.html
I have a simple RMI 'compute' server application (similar to this) that accepts objects of some interface type from clients over RMI, executes the compute() method of the received object and returns the result over RMI to the remote client. The jobs are 'one-offs' and there is no interaction between the different jobs or between objects of different jobs.
I would like to be able to modify classes and submit instances to the compute server for execution without constantly restarting the server JVM. However when a class that has been modified is submitted again as a parameter to a remote call it's method behaviour does not change (this occurs with anonymous classes also). I have been reading up about serialization and I realise that this is to do with the ClassLoader being unable to modify existing classes.
From my reading on SO and elsewhere I realise that somehow the ClassLoader that loaded the stream class must be GC'd and replaced in order to load a new version of my class. I have an idea how to do this but the situation seems complicated by the underlying RMI runtime and it having its own RMIClassloader.
My question is: What would be the easiest way to load each new version of a class received via RMI parameters. Ideally I'm looking for a way to have each remote call get a new ClassLoader and to dispose of it upon return. Is this feasible to do without an intricate knowledge of customised ClassLoaders and the internals of RMI?
Any pointers to reading materials or examples welcome!
Edit: here is the compute server's remote interface:
public interface ComputationEngine extends Remote {
public Object execute(Task t) throws RemoteException;
}
and the 'compute job' interface, Task:
public interface Task extends java.io.Serializable {
public Object compute();
}
The only way to this is to have a new ClassLoader when you want to change a Class.
How about making use of the URLClassLoader and making the code available from a URL
I use it in one of my projects to update APIs when the jar file changes. Take a look here:
http://code.google.com/p/open-forum/source/browse/trunk/Wiki/org/one/stone/soup/wiki/jar/manager/JarManager.java
Line 184+
Check your emails :-)
This isn't really answering your question, but it might be possible to make changing part of your classes into data instead of the actual class. Use a Map instead of fields, etc. You'd have a lot fewer classes floating around, and your code would probably be simpler too.