Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[RMI] Problème de déploiement d'une classe

1 réponse
Avatar
sylsau
Bonjour,

Je viens de commencer =E0 =E9tudier les RMI =E0 la fac.
Je me suis donc fait un petit exemple pour tester tout =E7a.
Ici, j'ai juste d=E9fini un objet op=E9rateur arithm=E9tique pr=E9sent sur
le serveur qui se chargera de faire des calculs basiques.

Voici l'interface de cet objet :

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Calculette extends Remote
{
Integer addition(Integer op1, Integer op2) throws RemoteException;
Integer soustraction(Integer op1, Integer op2) throws RemoteException;
Integer mul(Integer op1, Integer op2) throws RemoteException;
Integer div(Integer op1, Integer op2) throws RemoteException;
}

J'ai =E9galement =E9crit une classe impl=E9mentant cette interface :


import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class ImplCalculette extends UnicastRemoteObject implements
Calculette
{
public ImplCalculette() throws RemoteException
{
super();
}

public Integer addition(Integer op1, Integer op2)
{
return new Integer(op1.intValue() + op2.intValue());
}

public Integer soustraction(Integer op1, Integer op2)
{
return new Integer(op1.intValue() - op2.intValue());
}

public Integer mul(Integer op1, Integer op2)
{
return new Integer(op1.intValue() * op2.intValue());
}

public Integer div(Integer op1, Integer op2)
{
return new Integer(op1.intValue() / op2.intValue());
}
}

Enfin, voici les codes du client et du serveur :

- Client


import java.rmi.Naming;
import java.rmi.RemoteException;

public class ClientCalculette
{
public static void main(String[] args) throws RemoteException
{
Calculette cc;
Integer op1 =3D new Integer(2);
Integer op2 =3D new Integer(3);

try
{

cc =3D (Calculette) Naming.lookup("/CalcMachine");
System.out.println(cc.addition(op1,op2));

}catch(Exception e){

System.out.println("\n\nException dans le client : \n " +
e=2EgetMessage() + " \n\n");
e.printStackTrace();

}
}
}




- Serveur



import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
import java.rmi.server.UnicastRemoteObject;

public class ServCalculette
{
public static void main(String[] args)
{
try
{
ImplCalculette obj =3D new ImplCalculette();
// Liaison de l'objet dans le registre sous le nom "CalcMachine"
Naming.rebind("//localhost:1099/CalcMachine", obj);
System.out.println("Liaison de CalcMachine reussie !");

}catch(Exception e){

System.out.println("\nProbleme dans le bind au registry : \n " +
e=2EgetMessage());
e.printStackTrace();

}
}
}



Bon je suis arriv=E9 =E0 faire tourner cet exemple correctement sur mon
ordinateur.

Maintenant, j'aimerais pouvoir ajouter =E0 cet objet op=E9rateur
arithm=E9tique une m=E9thode incremente qui ajoute 1 =E0 un objet Entier
pass=E9 en param=E8tre.
Pour cela, j'ai cr=E9e une classe Entier que je vais passer en
param=E8tre =E0 cette fonction incremente.

Voici ma classe Entier :


import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Entier extends UnicastRemoteObject
{
private int valeur;

public Entier(int v) throws RemoteException
{
valeur =3D v;
}

public Entier(Integer v) throws RemoteException
{
valeur =3D v.intValue();
}

public int getValeur() throws RemoteException
{
return valeur;
}

public Integer getInteger() throws RemoteException
{
return new Integer(valeur);
}

public void inc() throws RemoteException
{
valeur++;
}
}



Mon probl=E8me est que je n'arrive pas =E0 voir comment je dois d=E9ployer
cette classe pour pouvoir l'utiliser. Pour le moment, j'ai test=E9 de
mani=E8re simple en mettant la classe Entier sur le serveur et le client
et en faisant des appels normaux c=F4t=E9 client sur l'objet entier comme
suit :


Entier ent =3D new Entier(4);
.=2E.
cc.incremente(ent);
.=2E.


Et l=E0 j'obtiens l'erreur suivante :

Exception dans le client :
argument type mismatch


java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:3=
9)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImp=
l=2Ejava:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294)
at sun.rmi.transport.Transport$1.run(Transport.java:153)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
at
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
at
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:=
701)
at java.lang.Thread.run(Thread.java:595)
at
sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemote=
Call.java:247)
at
sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:126)
at ImplCalculette_Stub.incremente(Unknown Source)
at ClientCalculette.main(ClientCalculette.java:24)



O=F9 la ligne 24 est la ligne de "cc.incremente(ent)".

Quelqu'un pourrait il m'indiquer une piste de d=E9ploiement =E0 mettre en
oeuvre ?

Merci d'avance de votre aide.

1 réponse

Avatar
TestMan
Bonjour,

Je viens de commencer à étudier les RMI à la fac.
Je me suis donc fait un petit exemple pour tester tout ça.
<...>

Maintenant, j'aimerais pouvoir ajouter à cet objet opérateur
arithmétique une méthode incremente qui ajoute 1 à un objet Entier
passé en paramètre.
Pour cela, j'ai crée une classe Entier que je vais passer en
paramètre à cette fonction incremente.

Voici ma classe Entier :


import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Entier extends UnicastRemoteObject
{
private int valeur;

public Entier(int v) throws RemoteException
{
valeur = v;
}

public Entier(Integer v) throws RemoteException
{
valeur = v.intValue();
}

public int getValeur() throws RemoteException
{
return valeur;
}

public Integer getInteger() throws RemoteException
{
return new Integer(valeur);
}

public void inc() throws RemoteException
{
valeur++;
}
}


Mon problème est que je n'arrive pas à voir comment je dois déployer
cette classe pour pouvoir l'utiliser. Pour le moment, j'ai testé de
manière simple en mettant la classe Entier sur le serveur et le client
et en faisant des appels normaux côté client sur l'objet entier comme
suit :


Entier ent = new Entier(4);
...
cc.incremente(ent);
...


Et là j'obtiens l'erreur suivante :

Exception dans le client :
argument type mismatch


java.lang.IllegalArgumentException: argument type mismatch
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
sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294)
at sun.rmi.transport.Transport$1.run(Transport.java:153)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
at
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
at
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
at java.lang.Thread.run(Thread.java:595)
at
sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
at
sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:126)
at ImplCalculette_Stub.incremente(Unknown Source)
at ClientCalculette.main(ClientCalculette.java:24)



Où la ligne 24 est la ligne de "cc.incremente(ent)".

Quelqu'un pourrait il m'indiquer une piste de déploiement à mettre en
oeuvre ?

Merci d'avance de votre aide.


Bonjour,

De rien ;)

Commencez par rajouter à votre client un
http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/RMISecurityManager.html

Ensuite, je ne suis pas sûr de ce que vous cherchez à faire :
- passer Enter au serveur "par valeur", auquel cas il doit implementer
Serializable
- passer Entier au serveur "par référence" (dans le style des
"callback"): auquelcas il doit implémenté une interface qui dérive de
Remote qui permettra au serveur de l'utilisé, une fois appelé par le
client : UnicastRemoteObject.exportObject(ent);

Voir http://www.ryerson.ca/~dgrimsha/courses/cps841/RMICallbacks.html

A+
TM