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.
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 want to make a small network game of two clients sending messages to eachother.
I'm new to sockets and serialization but I read that sending serialized objects via sockets is the way to do.
My problem is, I have multiple types of messages. One might be a simple chat message, the other one a turn (message) like a "NewObjectMessage" or "MoveObjectMessage"...
In tutorials I always read something like
MyClass myClass = (MyClass) objectinputstream.readObject();
which does a casting to the one specific class I put in the stream on the other side.
Question is: is there any way of determining what kind of message I get?
I'm looking for something like
stream.peekObject()
or something in order to see it's type.
Or is the common way to send two messages and the first one is only a declaration telling what comes next? But what happens if some packages get mixed up and the next object is not the one I was asking for?
So what is the best way to communicate between the clients in a way of e.g. moving an object and creating an object (or writing a message etc.)?
Thanks for your help!
Just read the object as an Object, and use instanceof to see what type it is.
Or have the objects all implement a common interface with an action method and just cast to the interface and call the method.
I think what you are looking for is object.getClass().getName();.
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 attempting to write two Java programs.
One to simulate a server, and one to simulate a client.
How could I go about sending an instance of a Response class over a socket?
The Response class represents status codes of the server connection. e.g. 404 Not Found etc
I'm not allowed to use Serialisation unfortunately.
Any advice would be greatly appreciated.
At some level Serialization must occur in order to send an object across a connection. I can only assume your comment about being not allowed to use serialization refers to not being able to use Serializable instead of a blanket prohibition of serialization(which makes no sense). A very simple method to accomplish this would be the use of a external serialization library such as gson. Gson serializes an object into a JSON string that you can transmit over your socket and then using the same library deserialize it back into an object on the other side. You can of course use any of your preferred serialization libraries with your favorite format eg. XML, json, YAML,...
You wouldn't be sending an instance of the Response class itself. When sending things over a network, client and server machines understand bytes. Your application can understand more than bytes, it can understand specific representations. For example, your server might send a JSON representation of your Response class like:
{
"response" : {
"code":404
}
}
Then your client must be able to understand what this sequence of bytes means. That's basically what a protocol is: how two machines can communicate.
Regardless of what language the server or clients are written in, the Response is an Entity. In Java you might use a Class to represent it, in C++ you might use a struct. However, both would need to know that when you are communicating with an external application.system, they would have to put it in a format that everyone understands, be it json, xml, or any other.
As for sending this through sockets, Oracle has a nice tutorial here. You get the OutputStream
from the socket and start writing your representation.
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.