Code mobile : Un exemple
DEA - Modélisation et implémentation des systèmes complexes -
D. Olivier
Année 2002/2003
1 Introduction
Avec la machine virtuelle Java, la sérialisation et RMI, il est possible de réaliser du code mobile.C’est l’objectif de ce document de présenter
un tel exemple.
C’est un exemple très simple, dans lequel on définit un code mobile, donc serialisable, un serveur qui met à disposition ce code mobile et
un client éventuellement distant. Le serveur est un objet distribué RMI qui pour l’exemple développé va créer son propre registre RMI.
2 Mise en œuvre
On définit quatre classes Java :
Agent qui correspond au code mobile, cette classe stocke une information (donnee) initiale qui est succeptible d’être modifié par les
clients, lorsqu’ils éxécutent ce code mobile. On stocke également la machine d’origine.
AgentFactory, c’est l’interface de l’objet serveur distribué. Cette interface est invoquée par le client et les appels de méthodes sont
gérés par RMI.
AgentFactoryImpl,c’est l’implementationde l’interface. Elle créeune instance dela classe Agent (objetmobile) et l’envoieau client
sur demande getAgent(). Cette classe accepte également des instances de la classe Agent et récupère la modification de donnée.
AgentClient qui comme son nom l’indique est le client du serveur. Il récupère tout d’abord la référence de l’objet serveur (Agent-
Factory) dans le registre RMI, puis fait migrer l’objet mobile Agent et exécute les méthodes de l’objet mobile.
2.1 La classe Agent
Définition du code mobile :
package mobile ;
import java . net . ; / / Pour o b t e n i r le nom des machines
public class Agent implements j ava . i o . S e r i a l i z a b l e / / I nd is pe ns ab le pour l a m ob il it é
{int donnee ; / / L i nfo stockée
S tr in g o r i g in e ; / / La machine d ’ o r i g in e
public Agent ( ) throws UnknownHostException / / Exception pouvant e t r e le vé e
{orig in e = InetAddress . getLocalHost ( ) . toString ( ) ;
}
public void c a lcule ( ) / / La fon cti on du code mobile
{
Université du Havre
donnee += 1 13;
}
public int getDonnee ( )
{return donnee;
}
public void setDonnee ( int donnee)
{this .donnee = donnee;
}
public St rin g douViensTu ()
{return o r igine ;
}
public St rin g ouEsTu ( ) throws Exception / / Pour c o n n a îtr e la machine où se
/ / s i t u e l e code qui s e xé cut e
{return InetAddress . getLocalHost ( ) . to Strin g ( ) ;
}
}
2.2 La classe AgentFactory
Interface permettant la mobilité :
package mobile ;
import java . rmi . ;
public interface AgentFactory extends Remote
{/ / Pour f a i r e migrer l e code ( à l a demande )
public Object getAgent ( ) throws Exception ;
/ / Pour ré cup ér er l e r é s u l t a t du t r ai te m en t du code mobile
public void setAgent ( Object a ) throws Exception ;
}
On peut remarquer que l’on manipule que des Object, ceci permet de la généricité. D’une part, on peut de ce fait faire migrer tout objet
serialisable, d’autre part cela ne nécessite pas du coté client de connaître la classe Agent au moment de la compilation.
2.3 La classe AgentFactoryImpl
Le serveur est donc la mise en œuvre de l’interface :
package mobile ;
import java . rmi . ;
import java . rmi . ser ver . ;
import jav a . rmi . r e g i s t r y . ;
public cl a ss AgentFactoryImpl extends UnicastRemoteObject implements AgentFactory
Université du Havre
{int data = 0; / / S ert à f ix e r la donnée i n i t i a l e vé hic ulé e
/ / par l e code mobile et à ré cup ére r la
/ / v a le ur l or sq ue l e code r e v ie n t en son s e in .
public AgentFactoryImpl ( ) throws RemoteException
{super();
}
public Object getAgent ( ) throws Exception / / Permet l a migration
{Agent a = new Agent ( ) ;
a . setDonnee ( this . d at a ) ;
return a ;
}
public void setAgent ( Object a ) throws Exception / / R éc upé ra tio n du r é s u l a t
{this . dat a + = ( ( Agent ) a ) . getDonnee ( ) ;
System . out . p r i n t l n ( " M aintenant l ’ agent es t en : "+
( ( Agent ) a ) . ouEsTu ( ) ) ;
}
public s t a ti c void main ( S tr in g [ ] argv ) / / argv [ 0 ] = = p or t
{try {LocateRegistry . c r e a t e R e g is t r y ( I n t e g e r . p ar s eI n t ( argv [ 0 ] ) ) ; / / Création d ’ un r e g i st re RMI
System . out . p r i n t l n ( " R eg is tr e RMI lan cé " ) ;
LocateRegistry . ge tRe gis try ( / / Enregistrement du serv eur dans le r e g i s t r e
Inte ge r . pa rs eI nt ( argv [ 0 ] ) ) . bind ( " AgentFactory " , new AgentFactoryImpl ( ) ) ;
System . out . p r i n t l n ( " Agent f ac t o ry e n r e g i s t r é " ) ;
}
catch ( Exception e )
{System . out . p r i n t l n ( " Exception i n t e r c e p t é e : " + e ) ;
e . p rin tSt ack Tra ce ( ) ;
}
}
}
2.4 La classe AgentClient
Dans cette classe, on utilise la réflexivité de Java pour connaître la classe et les méthodes de l’objet qui a migré. Une fois les méthodes
connues ont peu les invoquer.
package mobile ;
import java . rmi . ;
import java . rmi . ser ver . ;
import java . net . ;
import jav a . lang . r e f l e c t . ; / / Pour l a r e f l e x i v i t é des c la s se s
Université du Havre
public cl a ss AgentClient
{public s t a ti c void main ( Stri ng [ ] argv ) / / argv [0]== machine ser veu r
/ / argv [1]== por t
{try
{/ / Phase d ’ i n i t i a l i s a t i o n :
/ / 1 L ia iso n à l o b je t d i s t r i b u é s e rv eu r de code mobile
/ / 2 Migration du code sous l a forme d ’ un o b je t
St rin g u rl = " rmi : / / " +argv [0]+ " :" +argv [ 1 ] ;
System . out . p r i n t l n (" > Lancement du c l i e n t " ) ;
/ / Pour c o n t ro l e r l e s c hargements dynamiques ( f i c h i e r a gen ts . p ol ic y )
System . setSecurityManager (new RMISecurityManager ( ) ) ;
/ / Récupération de l a réfé r e n c e du se rve ur
AgentFactory a f = ( A gentFactory ) Naming . lookup ( u r l + " / Ag entFactory " ) ;
System . out . p r i n t l n (" > On a obtenu l a r éf é re n ce du Serveur " ) ;
Object a = af . getAgent ( ) ; / / Migration du code , a e s t l i ns tance
/ / On u t i l i s e le code mobile obtenu
Class cl = a . g etC las s ( ) ; / / On récupère la c l a s s e de l o b j e t qui
/ / a migré .
System . out . p r in t ln ( " Classe de l obje t obtenu : "+ cl . getName ( ) ) ;
System . out . p r i n t l n (" > L agent mobile e s t obtenu " ) ;
Method ou = cl . getMethod ( " douViensTu " , null ) ; / / On cherche l a méthode douViensTu ( )
/ / puis on invoque la méthode
System . out . p r i n t l n ( "L agent v ien s de : "+ ou . invoke ( a , null ));
ou = c l . getMethod ( " ouEsTu " , null ) ;
System . out . p r i n t l n ( " M aintenant l agent e s t en : " + ou . invoke ( a , null ));
Method getDonnee = cl . getMethod ( " getDonnee " , null ) ;
System . out . p r i n t l n ( "Donnee avant c a l cu l : " + ( ( I n te g e r ) getDonnee . invoke ( a , null ) ) . intValue ( ) ) ;
cl . getMethod ( " calc ul e " , null ) . invoke ( a , null ) ;
System . out . p r i n t l n (" > L agent mobile c a lc u l e " ) ;
getDonnee = cl . getMethod ( " getDonnee " , null ) ;
System . out . p r i n t l n ( "Donnee a pr ès c a lc u l : " + ( ( I n te g er ) getDonnee . invoke ( a , null ) ) . intValue ( ) ) ;
/ / On renvoie le code au ser veu r
af . s etAgent ( a ) ;
System . out . p r i n t l n (" > L agent e s t r e p a r t i " ) ;
}
catch ( Exception e )
{System . out . p r i n t l n ( " E xception i n t e r c e p t é e " + e ) ;
e . p rin tSt ack Tra ce ( ) ;
}
}
}
Université du Havre
2.5 Compilation et exécution
Coté serveur :
[serveur]$ ls
mobile/
[serveur]
[serveur]$ ls mobile/
Agent.java AgentFactory.java AgentFactoryImpl.java
[serveur]$ javac mobile/*.java
[serveur]$ rmic -v1.2 -d . mobile.AgentFactoryImpl
[serveur]$ ls mobile/
Agent.class Agent.java
AgentFactory.class AgentFactory.java
AgentFactoryImpl.class AgentFactoryImpl.java
AgentFactoryImpl_Stub.class
Au niveau compilation, il n’y a plus rien à faire, cependant il reste un problème au niveau du stub. En effet, le client doit posséder
le code de la classe de stub, de même notre objet distribué serveur renvoie des objets que le client n’est pas supposé connaître ini-
tialement puisque le code doit migrer. Une manière simple de procéder est de copier les .class correspondant sur le système de
fichier local du client, un comble pour du code mobile! Nous n’allons pas procéder de cette façon, mais rendre ces classes dispo-
nibles coté serveur. Cela nécessite que du coté serveur, il y ait un serveur http. Dans ce cas, on place les fichiers Agent.class et
AgentFactoryImpl_Stub.class, à l’aide d’un lien symbolique par exemple, dans un répertoire accessible par http.
ex : ~/public_html/rmi/download/mobile
Il ne nous reste plus qu’à lancer le serveur.
[serveur]$ java -Djava.rmi.server.codebase=http://unemachine/~untel/rmi/download/\
> mobile.AgentFactoryImpl 1099 &
[1] 6674
[serveur]$ Registre RMI lancé
Agent factory enregistré
Le serveur tourne donc maintenant, il reste à s’occuper du client.
Coté client :
[client]$ ls
agents.policy mobile/
[client]$ ls mobile
AgentClient.java AgentFactory.java
javac mobile/AgentClient.java
[client]$ ls mobile/
AgentClient.class AgentClient.java
AgentFactory.class AgentFactory.java
[client]$
On remarquera qu’il faut au client et au serveur l’interface AgentFactory.java. Ensuite on peut lancer l’exécution, mais il faut au
préalable définir un fichier *.policy pour le gestionnaire de sécurité.
gr ant
{permission java . net . SocketPermission
" :1024 65535" , " connect " ;
permission java . net . SocketPermission
" :80" , " connect " ;
};
On autorise les ports supérieurs à 1024 et le port http.
[client] java -Djava.security.policy=agents.policy mobile.AgentClient\
Université du Havre
1 / 6 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !