通过套接字发送匿名类?(Java中的Object..Stream)

Avo*_*dro 5 java class objectoutputstream objectinputstream classnotfoundexception

所以现在,我有一个运行的服务器ObjectInputStreamObjectOutputStream.

我遇到的问题是我有一个自定义(匿名)类,它扩展java.lang.Date了我试图发送到客户端然后编译.

所以我没有在客户端定义类,但我想以编程方式编译类.我尝试了很多不同的方法,但每次我得到一个ClassNotFoundException因为该类最初不在客户端.

Class<?> dateClass = (Class<?>) in.readObject(); //This is where the CNF Exception occurs
Compiler.compileClass(dateClass);
Run Code Online (Sandbox Code Playgroud)

mer*_*ike 7

Java Serialization机制假定反序列化JVM已知类,它不发送类定义.特别是,当你序列化一个Class对象,你不发送字节代码,该类但只指示接收VM来查找Class对象的一类具有特定名称.

另请注意,Class对象表示JVM中定义的类,即类的字节码已加载.加载类之后尝试编译到类以生成该字节码是没有意义的.

因此,我们需要以某种方式将类定义提供给客户端.最简单的方法就是做这个像任何其他类客户需求(通过在客户端的jar文件打包,或任何手段使用安装客户端PROGRAMM).如果这不可能,您可以通过网络加载类定义,例如使用a 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());
    }
Run Code Online (Sandbox Code Playgroud)