【问题标题】:Send an Anonymous class over sockets? (Object..Stream in Java)通过套接字发送匿名类? (Java 中的对象..流)
【发布时间】:2012-03-15 23:30:31
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: java class classnotfoundexception objectoutputstream objectinputstream


    【解决方案1】:

    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());
        }
    

    【讨论】:

    • 这比关于匿名化的精辟要好得多,尽管这是一个有趣的词。像“果冻”和“wibble”。因此,如果我们对有趣的词进行投票,那么这个答案现在应该会吸引这些投票。
    • 这就是我最初的想法。通过网络发送班级的文件,然后在到达那里时将其安装到 DIR。感谢您的保证:D
    • 您应该可以通过网络类加载器发送匿名类 - 例如,使用 rmi 类加载是执行此操作的本机 java 方式
    • 序列化payload.getClass() 并通过网络发送到另一端重建还不够吗?为什么需要序列化payload 实例?
    猜你喜欢
    • 2019-04-21
    • 2014-01-11
    • 2021-01-11
    • 2012-08-29
    • 1970-01-01
    • 2012-03-13
    • 2015-08-31
    • 1970-01-01
    相关资源
    最近更新 更多