deniger
2002-10-12
Présentation des premières étapes à suivre pour intégrer un
code de calcul dans un environnement objet distribué.
Intégration d'un code de calcul
Dans ce document, nous supposerons que le code concerné se nomme
Exemple . Il s'agit de définir et d'implanter les interfaces de
communication de ce code. A la fin de ce document, il sera possible de lancer
le code de calcul exemple à distance (grâce à IDL/CORBA) et à
partir de code java. Lors de la création de votre projet, vous devez suivre les spécifications
de dodico
Etape 1: l'exécutable
Dans un premier temps, il faut s'assurer que le code s'exécute correctement
sous tous les systèmes d'exploitation ( Windows, Unix/Linux,...). Dans la plupart
des cas, il faut créer des scripts de lancement afin de pouvoir exécuter le
code à partir d'une ligne de commande. Le code de calcul vag peut
être utilisé comme exemple.
Les exécutables et les scripts de lancement seront disposés dans le dossier
dodico_serveurs/exemple . Si la licence le permet, les sources
peuvent être ajoutées au dossier dodico_serveurs/src/exemple/ .
Etape 2: L'interface idl
Le fichier IDL
Il s'agit maintenant de créer les interfaces et les structures
de communication du code. Elles seront définies dans le module
exemple du fichier dodico_idl/code/exemple.idl (
un fichier IDL est proposé ci-dessous). Les structures
doivent suivre le plus fidèlement possible l'architecture des fichiers
d'entrée-sortie du code. Les signatures des 3 interfaces (IParametresExemple ,
ICalculExemple et IResultatsExemple ) doivent être
respectées.
/* * @file exemple.idl * @creation 2002-07-21 * @modification $Date: 2004/05/05 12:36:03 $ * @license GNU General Public License 2 * @copyright (c)1998-2001 CETMEF 2 bd Gambetta F-60231 Compiegne * @mail devel@fudaa.org */
|
#ifndef _EXEMPLE_IDL
#define _EXEMPLE_IDL
|
#include "general/calcul.idl"
|
/** * Un exemple .... * @version $Id: integration.xml,v 1.2 2004/05/05 12:36:03 deniger Exp $ * @author Fred Deniger */
|
module exemple
{
|
struct SParametres
{
chaine nom;
temps t;
...
};
struct SParametres02
{
...
};
|
struct SResultats
{
...
};
|
interface IParametresExemple : ::calcul::IParametres
{
attribute SParametres parametres;
attribute SParametres02 parametres02;
};
|
interface IResultatsExemple : ::calcul::IResultats
{
SResultats resultats();
};
|
interface ICalculExemple : ::calcul::ICalcul
{
};
|
};
#endif
|
La génération des fichiers java
Le fichier IDL définit les objets qui seront accessibles par l'intérmédiaire
de l'architecture CORBA. Pour utiliser ces objets distribués, il faut créer les
"classes" qui vont effectuer les tâches définies. Dans le cas de Fudaa, le code
IDL est projeté dans le langage Java, le bus utilisé est celui du JDK 1.3
(Corba 2.0) et l'héritage des classes d'implantation est assurée par la technique
de délégation ("tie"). Il est conseillé de lire le document de SUN sur le langage IDL
(cf la page des liens) et plus
particulièrement la partie "Implementing Inheritance" du chapitre "Extending Hello World".
Il s'agit maintenant de générer le source java correspondant au fichier
exemple.idl . La manière la plus simple pour générer le code est
d'utiliser l'outil ant et la cible IDLJ ( équivalent du compilateur IDL-to-Java
). Sous unix/linux, il est possible d'utiliser le script jaidl1.3
et la commande jaidl1.3 code/exemple
Dans notre exemple, les fichiers seront générés dans le dossier
dodico_java_genere/org/fudaa/dodico/corba/exemple . Ces classes
doivent être compilées dans le dossier classes de dodico: la cible
IDLJ de ant (de dodico !) ou le script jacgen :
ant IDLJ
Il est maintenant possible d'écrire les classes d'implantation des 3
interfaces.
L'équivalence IDL-JAVA
Les structures IDL deviennent des classes contenant des champs publiques. Voici
un exemple d'utilisation de SParametres:
SParametres param=newSParametres();
param.nom="essai1";
param.t=5;
|
une interface IDL représente un objet distant
et plusieurs fichiers importants sont générés pour une interface. Pour l'interface
ICalculExemple :
-
_ICalculExempleStub.java :
- une classe du côté client (le
"stub") qui transmet au serveur les commandes de l'application cliente
-
-
ICalculExemple_Tie.java :
- une classe du côté serveur (le
"skeleton") qui reçoit les invocations distantes et les transmet aux classes
exécutantes ( "servant" )
-
-
ICalculExempleHelper.java , ICalculExempleHolder.java ,...:
-
-
ICalculExempleOperations.java :
- une interface qui sera implantée par votre classe d'implantation
DCalculExemple.java
(la classe "servant").
Etape 3 : Les classes d'implantation java
Exemple de structure
Il s'agit maintenant de créer et de compléter les 3 classes
(DParametresExemple , DCalculExemple et
DResultatsExemple ) qui se trouveront dans le dossier
dodico_java_ecrit/org/fudaa/dodico/exemple/ . Nous prendrons le cas
de DCalculExemple :
package org.fudaa.dodico.exemple;
import org.fudaa.dodico.corba.objet.*;
import org.fudaa.dodico.objet.*;
import org.fudaa.dodico.corba.calcul.*;
import org.fudaa.dodico.calcul.*;
import org.fudaa.dodico.corba.exemple.*;
import org.fudaa.dodico.fortran.*;
|
publicclass DCalculExemple
extends DCalcul
implements ICalculExempleOperations,ICalculExemple
{
|
publicDCalculExemple()
{
super();
}
|
public String description()
{
return"Exemple, "
+super.description();
}
|
publicvoidcalcul(IConnexion c)
{
}
|
}
|
A ce stade du développement, vous pouvez écrire la structure des 2 autres
classes d'implantation DParametresExemple.java et
DResultatsExemple.java . Pour compiler vos classes, la cible
compileJavaEcrit de ant ou la ligne de commande jac exemple
pourront être utilisées.
L'usine
Pour créer les objets à distance, une usine est utilisée. Celle-ci est
générée automatiquement à partir des sources idl et java ( voir les
spécifications de nommage pour
connaître les quelques règles d'écriture).
le fichier idl general/usine.idl et java
usine/DUsine.java seront crées par la cible usine . Ces fichiers devront être également
compilés. La cible build permet de chaîner automatiquement toutes
les tâches nécessaires (il est fortement conseillé de l'utiliser au début).
Si le fichier idl est modifié
vous devez reprendre les étapes précédentes : generation du code java
(la tâche IDLJ ),
compilation du code généré (compileJavaGenere )
et compilation de votre code (compile ).
Si des interfaces ont
été ajoutées ou supprimées, il faut régénérer l'usine.
La cible IDLJ permet de chaîner automatiquement toutes
les tâches nécessaires. Pour recompiler le java, utiliser la tâche build .
Les méthodes de lecture et d'écriture des fichiers d'entrée-sortie
Ces méthodes sont des méthodes statiques qui se trouvent dans les classes
DParametresExemple et DResultatsExemple . En général,
elles utilisent les classes FortranReader ou FortranWriter
qui offrent des méthodes très pratiques pour gérer les fichiers de données.
Ces méthodes permettent de faire le lien entre les fichiers du code et les
structures IDL.
Pour notre cas, deux méthodes pourront être créées dans le fichier
DParametresExemple :
publicstaticvoidecritParametres(File _fic , SParametres _p)
throws IOException
|
publicstaticvoidecritParametres02(File _fic , SParametres02 _p)
throws IOException
|
et une dans DResultatsExemple :
publicstaticSResultatslitResultats(File _fic )
throws IOException
|
La méthode calcul de la classe DCalculExemple
Cette méthode doit permettre de :
-
écrire les fichiers de paramètres du code,
-
trouver et lancer le code de calcul,
-
lire le(s) fichier(s) de résultats,
-
informer de l'état d'avancement des opérations.
La fichier calcul/DCalcul.java fournit des méthodes intéressantes
pour gérer les fichiers, le chemin du serveur, ... Pour écrire cette méthode, vous
pouvez également vous aider des projets curvi ou vag .
La classe serveur par défaut
Pour chaque code, une classe serveur simple est proposée : il s'agit de
connecter un objet calcul à l'ORB. Dans notre cas, ce
sera la classe ServeurExemple (cf vag ).
Etape 4 : tests
Vous trouverez ci-dessous une classe qui permet de tester l'interface de
communication de votre code. Ce test doit connaître le chemin du serveur (le
code exécutable) et un fichier de parametres de ce code. Une méthode permettant
la lecture du fichier de paramètres doit être créée pour utiliser cet exemple
(il est également possible d'instancier la structure de paramètres dans la classe
test).
package org.fudaa.dodico.exemple;
import java.io.File;
|
import org.fudaa.dodico.objet.CDodico;
|
import org.fudaa.dodico.corba.objet.IConnexion;
import org.fudaa.dodico.corba.objet.IPersonne;
import org.fudaa.dodico.corba.objet.IOrganisme;
|
import org.fudaa.dodico.corba.usine.IUsine;
|
import org.fudaa.dodico.corba.exemple.ICalculExemple;
import org.fudaa.dodico.corba.exemple.IParametresExemple;
import org.fudaa.dodico.corba.exemple.IParametresExempleHelper;
import org.fudaa.dodico.corba.exemple.IResultatsExemple;
|
import org.fudaa.dodico.corba.exemple.SParametresExemple;
import org.fudaa.dodico.corba.exemple.SResultatsExemple;
|
publicclass ClientExemple
{ |
publicstaticvoidmain( String[] args)
{
if(args.length!=2)
{
System.out.println("ClientExemple <serveur> <fichier_entree>");
System.exit(1);
}
System.out.println("serveur "+args[0]);
System.setProperty("FUDAA_SERVEUR",args[0]);
File entree=newFile(args[1]+".extension");
if( !entree.exists() )
{
System.out.println(entree.getAbsolutePath()+" non trouvé");
System.exit(1);
} |
System.out.println("création du serveur");
//Creation de l'usine de base
UsineLib.setAllLocal(false);
IUsine usine=UsineLib.creeUsine();
//Creation d'une personne (et son organisme)
IPersonne p=usine.creeObjetPersonne();
IOrganisme o=usine.creeObjetOrganisme();
|
o.intitule("sans");
p.organisme(o);
p.nom("test");
|
//Creation du serveur de calcul et connexion de la personne
ICalculExemple calcul=usine.creeExempleCalculExemple();
|
IConnexion connexion=calcul.connexion(p);
|
IParametresExemple params=
IParametresExempleHelper.narrow(calcul.parametres(connexion));
|
System.out.println("lecture des parametres");
try
{
params.parametresExemple(DParametresExemple.litParametresExemple(args[1]));
|
System.out.println("lancement calcul");
calcul.calcul(connexion);
|
System.out.println("calcul termine");
}
catch(Exception e)
{
System.out.println(e);
}
}
} |
La partie dodico est terminée. La prochaine étape: construction de l'interface
graphique
|