问题
I'm having following problem: My project consists out of two packages (Client and Server), where each of them has the class Package
. Now i want to send this class over the network via ObjectOutputStream
/ ObjectInputStream
like this:
//Client - this is in package client
ObjectOutputStream out = new SocketOutputStream(socket.getOutputStream);
Package package = new Package();
out.writeObject(package);
//Server - this is in package server
ObjectInputStream in = new SocketInputStream(socket.getInputStream);
Object o = in.readObject();
if(o instanceof Package) ... //do something important
So the problem lies in the last line, where I get a ClassCastException. The reason is obviously that he takes full path to determine the type of the object, so client.Package
is not server.Package
. The Problem is that i cannot put the client package to the server or vice versa.
So here is the real Question: Can i determine the type of the class without importing the Package class from the package (client / server)? Or is there a possibility to send the Object over the network without class information ?
Edit:
The Package class looks as following:
public class Package implements Seriablizable {
private static final long serialVersionUID = 5050301321863757269L;
public String objectName;
public Object[] parameters;
public Class[] parameterTypes; //parameter types
}
Already thanks for helping :)
回答1:
When you declare two classes with the same name in different packages, they are fundamentally different classes. That is why you are getting the exception when you attempt to cast from one type to the other.
The problem is that i cannot put the client package to the server or vice versa.
There is no way you can convince the Java type system that the two classes are the same. They are different.
The simplest solution is to create a third package that contains the classes that are needed on both the client and server side. Put the common package (or packages) into a JAR file, and add it to the classpath on the client and server sides.
There are other alternatives such as:
using a different marshalling / unmarshalling mechanism (JSON, XML, custom), or
using the available hooks in the Java serialization library to translate types (see @EJP's answer),
but (to mind) this problem is down to a design mistake, and the best approach is to fix that mistake soon rather than papering over it.
If you are passing objects from a java client to a java server via Java serialization, then you should be using the same classes on both sides. If that is not possible for a sound technical reason (as distinct from a design mistake), then that is most likely a good reason NOT to use Java serialization.
To answer your "real" questions:
Q: Can i determine the type of the class without importing the Package class from the package (client / server)?
Strictly yes, but it won't help you.
You can refer to a class by its fully qualified name; e.g.
if (o instanceof com.acme.WeaselTrap)
You can get the actual type's
Class
object.Class<?> clazz = o.getClass();
But once you have gotten there, you still have the issue that the two types with the same names in different packages are fundamentally different.
(Of course, if your code can cope with the classes being different, you could make your life simpler by changing the class names so that the simple names are different.)
Q: Or is there a possibility to send the Object over the network without class information ?
Not using Java serialization.
回答2:
The reason is obviously that he takes full path to determine the type of the object, so client.Package is not server.Package. The Problem is that i cannot put the client package to the server or vice versa.
You are just going to have to do exactly that, or put it into a third package that is accessible by both client and server.
Or else implement writeReplace()
or readResolve()
inside the classes, but that means that the class that does that has to know about the other class in the other package, which probably defeats your package issue as well in another way.
回答3:
Shouldn't your instanceof be Package not package? Since it is a class name.
You can send the object back and forth as xml or json. The data can marshalled and unmarshalled to and from whatever classes you want.
For example: Marshall/Unmarshall a JSON to a Java class using JAXB
回答4:
The reason it isn't working is because you likely haven't implemented Java's serialization mechanism into your class. As described here, all you should have to do is have your class implement java.io.Serializable. Even if the absolute paths are different, if the code is the same in client.Package and server.Package this will work fine. Note that if you have any structures within your Package class that are not native Java types, those will also have to implement java.io.Serializable.
来源:https://stackoverflow.com/questions/27367355/java-classcastexception-with-two-identical-classes-in-different-packages-sent-o