所以现在,我有一个运行 ObjectInputStream
和 ObjectOutputStream
的服务器。
我遇到的问题是我有一个扩展 java.lang.Date
的自定义(匿名)类,我正尝试将其发送给客户端然后进行编译。
所以我从来没有在客户端定义类,但我想以编程方式编译类。我尝试了许多不同的方法,但每次我都得到一个 ClassNotFoundException
,因为该类最初不在客户端。
Class<?> dateClass = (Class<?>) in.readObject(); //This is where the CNF Exception occurs
Compiler.compileClass(dateClass);
最佳答案
Java 序列化机制假定反序列化的 JVM 知道这些类,它不会发送类定义。特别是,当您序列化一个 Class
对象时,您不会发送该类的字节码,而只会指示接收 VM 查找该类的 Class
对象有一个特定的名字。
另请注意,Class
对象表示 JVM 中定义的类,即该类的字节码已被加载。在加载类之后尝试编译为类以生成该字节码毫无意义。
因此,我们需要以某种方式将类定义提供给客户端。最简单的方法是像客户端需要的任何其他类一样执行此操作(通过将其打包到客户端的 jar 文件中,或使用任何用于安装客户端程序的方式)。如果那不可能,您可以通过网络加载类定义,例如使用 URLClassLoader
,或者您可以通过序列化流发送类文件,并在客户端接收到它时使用 ClassLoader.defineClass
加载类。
PS:这个问题完全与类是否命名无关。以下测试代码表明匿名类的对象可以很好地序列化和反序列化(如果接收 VM 具有类定义):
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
Serializable payload = new Serializable() {
@Override
public String toString() {
return "hello from the anonymous class";
}
};
oos.writeObject(payload);
oos.writeObject(payload.getClass());
}
try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
System.out.println(in.readObject());
System.out.println(in.readObject());
}
关于java - 通过套接字发送匿名类? (Java 中的对象..流),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9448985/