2010-12-05 8 views
1

Je travaille sur un projet utilisant Java RMI. C'est le problème à l'origine de la classe:Sérialisation Java avec RMI

public class FSFile implements Serializable 
{ 
public static final int READ = 0; 
public static final int WRITE = 1; 

private int  flag; 
private String filename; 

private transient BufferedWriter writer; 
private transient BufferedReader reader; 

... 

private void writeObject(ObjectOutputStream stream) throws IOException 
{ 
    stream.defaultWriteObject(); 
    stream.writeObject(writer); 
    stream.writeObject(reader);  
} 

private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException 
{ 
    stream.defaultReadObject(); 
    writer  = (BufferedWriter) stream.readObject(); 
    reader  = (BufferedReader) stream.readObject(); 
} 
} 

Fondamentalement, j'utilise RMI pour envoyer cet objet fsfile à un autre processus localement (pour l'instant) et est là l'erreur que je reçois:

java.rmi.UnmarshalException: error unmarshalling return; nested exception is:                  
java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException; 
java.io.BufferedReader 

Pour être plus précis, il y a une classe nommée FileService qui utilise une fonction fetch() d'un FileServer pour obtenir un FSFile en retour. Il n'y a rien de spécial dans la fonction fetch(), il crée juste un fichier FSFile et le renvoie. Toutes les communications entre ces classes sont effectuées via RMI.

Comment se fait-il que j'ai une erreur comme celle-ci?

Répondre

3

Vous ne pouvez pas sérialiser les lecteurs et les écrivains. Cela n'a aucun sens. C'est comme essayer d'envoyer un téléphone sur une ligne téléphonique. Si vous voulez envoyer un fichier, envoyez le fichier.

Et votre code appelle simplement writeObject sur ces objets comme s'ils étaient Serializable. Ils ne le sont pas. Sinon, vous auriez pu les rendre non-transitoires et omettre complètement les méthodes readObject et writeObject personnalisées. Recoder simplement ce que le système aurait fait de toute façon ne change rien. Il ne fait certainement pas de classes sérialisables qui ne le sont pas.

+0

Vous me suggérez donc d'envoyer un fichier au lieu de mon cours personnalisé? Ce que je voulais faire est d'une extrémité, juste avec cet appel FSFile une lecture ou une écriture qui sera effectuée localement à l'autre extrémité. Ce que je voulais faire avec writeObject et readObject est juste de garder l'état de celui-ci. – David

+0

Le fait est que l'utilisateur distant ne peut pas écrire ni lire avec la classe Fichier. – David

+0

Non, je ne suggère pas d'envoyer un fichier. C'est juste un nom. Je parle d'envoyer le contenu. Si vous voulez implémenter une sorte de fichier distant avec des capacités d'E/S c'est une autre histoire, vous devez implémenter votre propre RemoteOutputStream etc. Pas trivial, pas impossible, pas un excellent moyen de concevoir un système IMO. – EJP

3

Si vous ne souhaitez pas réimplémenter l'envoi de fichiers/flux via RMI, vous pouvez rechercher dans RMIIO, il gère de telles choses de manière concise et efficace.