2009-06-02 10 views
2

J'ai le problème suivant: Je veux envoyer un type (java.lang.Class) sur le fil et "définir" la classe de l'autre côté.Comment envoyer une classe sur le fil

J'ai essayé comme ça:

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

et la réception:

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

donc évidemment je dois envoyer la bytecode première de la classe et faire un

ClassLoader.defineClass(bytes, .. 

mais malheureusement, je ne vois pas comment je peux récupérer le bytcode d'une classe chargée. Je cherche quelque chose comme:

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

Est-ce même possible avec JDK standard ou est-il une petite lib là-bas qui peut le faire?

+1

On dirait que vous essayez de réinventer RMI. –

Répondre

5

Je ne pense pas que ce que vous voulez est possible en toute généralité. Le fait de définir une classe à partir de son bytecode n'est pas réversible. Ce que vous devriez être en mesure de le faire, cependant, est de lire directement le fichier bytecode (en supposant que c'est un URLClassLoader):

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

Alternativement, vous pouvez simplement rendre les fichiers de classe accessibles via HTTP et utiliser directement un URLClassLoader sur le côté récepteur.

+1

Je pense que vous devrez tirer le contenu du fichier .class sur le fil, puis le reconstituer (soit dans le fichier ou dans la mémoire), et avoir un chargeur de classe charger ce fichier. Si vous reconstituez le fichier .class en tant que fichier, vous pouvez utiliser URLClassLoader. Si vous voulez le reconstituer en mémoire, vous devez probablement définir votre propre classloader. – Jared

+1

Vous n'avez pas besoin de le "reconstituer" pour utiliser un URLClassLoader. Il n'est pas nommé * URL * ClassLoader pour rien - il prendra heureusement une URL HTTP et fera tout le dur travail lui-même. C'est comme ça que ça fonctionne avec Applets, après tout. –

0

Vous devriez vérifier java serialization interface

modifier:

Je relis votre message et vous parlez de définir la classe de l'autre côté. Cela m'amène à penser que ce que vous essayez d'accomplir est distribute objects across the network.

En outre, si votre serveur et client partagent la même interface, vous pouvez simplement créer des objets via java reflection

+1

On dirait qu'il a besoin d'obtenir la classe DEFINITION à travers le fil, par opposition à une instance d'une classe. Avec des technologies comme RMI et même la réflexion, avoir la classe DEFINITION à la disposition du classloader est toujours une condition préalable. – Jared

+0

Eh bien, oui, mais le chargeur de classe peut charger le bytecode sur le fil. –

-3

Vous pouvez écrire votre propre méthode de sérialisation.

si

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. 

} 

C'est la méthode que nous mettons en œuvre en .Net pour la sérialisation. La clé de cette méthode est qu'elle vous met complètement en charge de la sérialisation. Il peut être long si vous n'avez pas de versions de ce type de communication, mais pour plusieurs versions à mesure que le produit se développe, c'est l'une des rares méthodes fiables que nous avons trouvé pour le faire. Nous utilisons des objets de flux de mémoire pour écrire chaque champ de données et cascader l'écriture d'objets complexes en implémentant l'interface iserialisable (qui n'existe peut-être pas en Java, mais c'est une interface simple à implémenter). Nous utilisons la même DLL sur le serveur d'entreprise que nous le faisons sur le client.

La sérialisation est un problème, peu importe la plateforme sur laquelle vous vous trouvez.

1

Vous ne pouvez pas le faire depuis la mémoire. Vous devez avoir les codes d'octets définissant la classe, qui pour la plupart des classes peuvent être trouvés en demandant à la JVM.Ce code de http://www.exampledepot.com/egs/java.lang/ClassOrigin.html devrait vous aider à démarrer:

// 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/ 
Questions connexes