2009-06-02 68 views
2

我有以下問題:我想通過電線發送一個類型(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在那裏,能做到嗎?

+1

聽起來像你正在試圖重塑RMI。 – 2009-06-02 22:39:25

回答

5

我不認爲你想要的是完全一般的可能性。從字節碼定義類的行爲是不可逆的。你應該能夠做到什麼,但是,是直接讀取的字節碼文件(假設它是一個URLClassLoader):

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

或者,你可以只通過HTTP使訪問的類文件,直接使用上URLClassLoader接收方。

0

您應該檢查java serialization interface

編輯:

我重新讀您的文章和你談論的是定義在另一邊的類。這導致我認爲你要完成的是distribute objects across the network

而且,如果你都服務器和客戶端共享相同的接口,你可以簡單地通過java reflection

+1

這聽起來像他需要通過電線獲得類DEFINITION,而不是類的一個實例。有了像RMI和反射這樣的技術,讓類加載器可以使用類DEFINITION仍然是一個先決條件。 – Jared 2009-06-02 21:45:42

+0

嗯,是的,但類加載器可以通過線加載字節碼。 – 2009-06-02 22:38:59

-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。

無論您使用哪種平臺,序列化都是一個問題。

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/