如何通过电线发送课程

时间:2009-06-02 21:22:22

标签: java serialization classloader

我有以下问题:我希望通过线路发送一个类型(java.lang.Class)并在另一侧“定义”该类。

我尝试过这样:

ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(MyClass.class);

并在接收端:

ByteArrayInputStream bis = new ByteArrayInputStream(request.getBytes());
ObjectInputStream ois = new ObjectInputStream(bis);
Class c = (Class) ois.readObject(); // ClassNotFoundException

所以显然我需要发送类的原始字节码并执行

ClassLoader.defineClass(bytes, ..

但遗憾的是我没有看到如何检索已加载类的bytcode。 我正在寻找类似的东西:

byte[] byteCode = MyClass.class.toByteArray();

这是否可以使用标准JDK,或者是否有任何小型lib可以做到这一点?

4 个答案:

答案 0 :(得分:5)

我不认为你想要什么是完全普遍的。从字节码定义类的行为是不可逆的。但是,您应该能够直接读取字节码文件(假设它是URLClassLoader):

MyClass.class.getResourceAsStream("Myclass.class")

或者,您可以通过HTTP访问类文件,并直接在接收方使用URLClassLoader

答案 1 :(得分:1)

你不能从记忆中做到这一点。您必须具有定义类的字节代码,通过询问JVM可以找到大多数类。来自http://www.exampledepot.com/egs/java.lang/ClassOrigin.html的代码可以帮助您入门:

// Get the location of this class
Class cls = this.getClass();
ProtectionDomain pDomain = cls.getProtectionDomain();
CodeSource cSource = pDomain.getCodeSource();
URL loc = cSource.getLocation();  // file:/c:/almanac14/examples/

答案 2 :(得分:0)

您应该检查java serialization interface

编辑:

我重新阅读了你的帖子,而你正在谈论在另一方面定义课程。这让我想到你要完成的是distribute objects across the network

此外,如果您的服务器和客户端共享相同的界面,您只需通过java reflection

创建对象

答案 3 :(得分:-3)

您可以编写自己的序列化方法。

所以

public byte[] Serialize()
{

// serialize each field in turn here.

return data;
}


public void Deserialize(byte[] data)
{

// deserialize data in the same order it was serialized.

}

这是我们在.Net中实现序列化的方法。这种方法的关键是它让你完全负责序列化。如果您不打算使用此类通信的任何版本,但随着产品的增长,这可能会很长,这是我们发现的少数可靠方法之一。

我们使用内存流对象来写出每个数据字段并通过实现iserializable接口(可能在java中不存在,但它是一个简单的接口来实现自己)来级联写入复杂对象。

我们在公司服务器上使用与客户端相同的dll。

无论您使用哪个平台,序列化都是一个问题。