Problème RMI : Invalid remote object

nasix
Problème RMI : Invalid remote object

Hello,

J'essaie de mettre un objet remote dans le registre (pour l'utiliser à distance) et ça ne marche pas :

Voici mon Interface Remote :

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Date;


public interface DateInterface extends Remote {
	Date getDate() throws RemoteException;
}

Voici ma classe d'implémentation :

import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.RemoteObject;
import java.util.Date;

public class DateImp extends RemoteObject implements DateInterface, Serializable {
	public Date getDate() throws RemoteException {
		return new Date();
	}
}

Je compile cette classe manuellement via javac, puis je génère le stub via rmic.

Juste après je lance mon registre via registry (ou en tâche de fond : start registry).

Par la suite je lance mon serveur :

import java.rmi.Naming;

public class ServerMain {	
	
	public static void main(String []args) {
		DateImp dt = new DateImp();
		try {
			Naming.bind("rmi://localhost:1099/dtService", dt);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Ceci lève l'exception suivante :

java.rmi.MarshalException: error marshalling arguments; nested exception is: 
	java.rmi.MarshalException: Invalid remote object
	at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
	at java.rmi.Naming.bind(Naming.java:111)
	at ServerMain.main(ServerMain.java:8)
Caused by: java.rmi.MarshalException: Invalid remote object
	at java.rmi.server.RemoteObject.writeObject(RemoteObject.java:347)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:917)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1339)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1290)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:302)
	... 3 more

Merci d'avance pour toute aide ou indication.

fredericmazue

Il me semble que ta classe serveur devrait étendre UnicastRemoteObject et implémenter ton interface:

Quote:

class ServerMain extends UnicastRemoteObject implements DateInterface {
//etc,etc
}

Attention aussi, (farce classique avec RMI) quand tu lances la registry celle-ci ne DOIT PAS voir la classe du serveur. Autrement dit ServerMain ne doit pas être dans le classpath quand tu lances la registry.

nasix

Salut,

Quote:
Il me semble que ta classe serveur devrait étendre UnicastRemoteObject et implémenter ton interface

Pour UnicastRemoteObject je ne sais pas pourquoi, mais pour mon interface je ne sais pas à quoi va me servir alors ma classe d'implémentation DateImp. Parce qu'il y aura une double implémentation. D'autant plus, ce n'est pas celle là ma classe distante, c'est plutôt DateImp.

Quote:
quand tu lances la registry celle-ci ne DOIT PAS voir la classe du serveur

Je lance rmiregistry avant de lancer le serveur, le serveur ne fait que mettre l'objet distant dans le registre par la méthode Naming.bind

fredericmazue

Quote:
mais pour mon interface je ne sais pas à quoi va me servir alors ma classe d'implémentation DateImp. Parce qu'il y aura une double implémentation. D'autant plus, ce n'est pas celle là ma classe distante, c'est plutôt DateImp.

Peut être bien que c'est ton implémentation qui ne sert à rien. Toujours est-il que le bazar te dit que ta classe distante est invalide "Invalid remote object "

Quote:
Je lance rmiregistry avant de lancer le serveur

ce n'est pas du tout ce que je t'ai dit si tu prends la peine de me lire.
Je t'ai dit qu'au moment où tu lance rmiregistry, le serveur ne doit pas être dans le classpath.

Tu sais RMI ce n'est pas une mince affaire à faire marcher. Tout ceux qui ont essayé te le diront :) Même en faisant très attention et en suivant les conseils.

Bonne chance :)

fredericmazue

salut nasix

Es tu arrivé à ce que tu voulais avec RMI; J'avais écrit un article sur ce sujet dans Programmez! il y a longtemps. plusieurs années. Je ne me rappelle plus le numéro.
Je voulais le mettre en tuto sur le site. Mais je n'ai pas le temps. :(
Si tu veux je peux t'en envoyer des morceaux si ça t'intéresse

nasix

Salut fredericmazue,

Je te remercie beaucoup, même si je ne suis pas encore arrivé à la solution. Si tu as de quoi me faire profiter, je t'en serais reconnaissant.

Bonne journée.

fredericmazue

allez je te propose un deal :)

1) Tu m'envoies ton adresse mail en privé
2) je t'envoie l'article avec les sources
3) Tu mets en ligne un tuto RMI sur le site. Sans te casser la tête. Tu fais des copier/coller

C'est ce que j'aurais fait de toutes façons, mais vraiment j'ai pas le temps :(

fredericmazue

Voilà le tuto est en ligne ici

nasix

Merci,

Je vais réessayer.

Bonne fin de soirée.

fredericmazue

C'était avec plaisir.
Bonne chance... RMI c'est capricieux.
Tiens nous au courant ici