Java - Ada france

publicité
Ada et Internet
Ada and the Internet
Conférence Ada-France dans le cadre du
workshop "Methods and Tools for Ada 95"
(Brest, 16 Septembre 1999)
J-P. Rosen: "Ada pour développer sur Internet"
S. Moody: "Ada and the Internet: Information
Linking, Agents and the scale of the Web"
T. Quinot: " CIAO: Opening the Ada 95
Distributed Systems Annex to CORBA Clients"
E. Briot: "JGNAT: The GNAT Ada 95
environment for the environment for the JVM"
Ada pour développer sur Internet
Jean-Pierre Rosen
Adalog
27, avenue de Verdun
92170 VANVES
FRANCE
Résumé
Ada permet de réaliser des applications liées à l’Internet
aussi bien que n’importe quel langage. Mais le terme "application Internet" englobe des besoins différents. On distingue les services de pages Web dynamiques côté serveur
(interface CGI), les animations de page côté client (Java),
et l’écriture d’application autonomes utilisant Internet.
Pour chacune de ces possibilités, des outils sont disponibles
facilitant l’écriture d’applications en Ada.
1 Introduction
On peut bien entendu réaliser en Ada tout ce qui peut se
faire dans d’autres langages. Mais en pratique, cela peut être
plus ou moins facile selon les bibliothèques dont on dispose. Dans ce papier, nous présentons rapidement les différentes facettes de la programmation Internet, et faisons un
panorama des services permettant de développer des applications liées à Internet en Ada, aussi bien en tant que client
qu’en tant que serveur.
2 L’interface CGI
L’interface CGI [1] (Common Gateway Interface, à ne
pas confondre avec la norme graphique Computer Graphic
Interface) permet de créer des pages Web dynamiques, c’est
à dire dont le contenu est fourni par l’exécution d’un programme et non sous la forme d’un fichier figé.
2.1 Principe de fonctionnement du CGI
Lorsqu’un serveur HTTP se voit demander une URL désignant un fichier figurant sous un répertoire spécial (souvent appelé CGI-BIN), il le considère comme un
exécutable, le lance, et renvoie le produit de sa sortie standard (le STANDARD_OUTPUT de Ada) au client. C’est aussi
simple que cela.
Enfin presque... Tout d’abord, le serveur doit connaître
le type des données renvoyées par le programme. Pour cela,
E-m: [email protected]
URL: http://pro.wanadoo.fr/adalog
le texte doit commencer par une ou plusieurs lignes fournissant des indications sur le contenu de ce qui suit. Ces lignes
d’en-tête sont séparées du contenu proprement dit par une
ligne vide. Cela peut être, par exemple :
Content-type: text/html
pour indiquer du HTML normal, ou :
Location: http://monserveur.fr/reponse
pour indiquer que la réponse se trouve dans un autre fichier.
Ensuite, il est bien évident que les pages dynamiques
n’ont d’intérêt que si elles permettent de répondre à une demande particulière du client ; il faut donc que le client passe
des données à l’application... et que celle-ci soit capable de
les récupérer.
Côté client, cela se fait en mettant dans l’URL, derrière
le nom du fichier, des indications de la forme Clé=Valeur,
séparées par des points d’interrogation. Dans les valeurs,
tous les espaces sont remplacés par des caractères "+", et
tous les caractères non alphanumériques sont représentés
par leur valeur hexadécimale sous la forme "%xx".
Noter que rien n’est imposé quant à la façon dont ces paramètres sont mis par le client dans l’URL : il est parfaitement possible de les mettre directement dans une référence
(balise HREF), mais en général ils proviendront d’un formulaire. Dans ce cas, le descriptif du formulaire contient
l’URL du fichier CGI à activer, et c’est le logiciel client qui
rajoute les noms et les valeurs des différents champs du formulaire derrière le nom du fichier.
Il existe plusieurs façons de récupérer ces valeurs côté
serveur, mais nous ne présenterons ici que la plus habituelle. Avant de lancer l’application CGI, le serveur HTTP initialise des variables d’environnement avec diverses
informations. La plus intéressante est QUERY_STRING, qui
contient la chaîne de caractère suivant le premier "?" dans
l’URL, c’est-à-dire tout l’ensemble des paramètres. Le logiciel n’a donc qu’à récupérer le contenu de cette variable, la
décoder, et produire ce qu’il veut en sortie.
Remarquer qu’avec l’interface CGI, l’application est
lancée sur le serveur, ce qui pourrait poser des problèmes de
sécurité. C’est pour cette raison que seuls les exécutables
"autorisés" (ceux du répertoire spécialement marqué dans le
serveur) peuvent être lancés de cette façon. En revanche,
il n’y a aucune restriction au type d’exécutable : ce peutêtre des programmes développés dans un langage conventionnel, ou des scripts en Shell, PERL, Tcl...
2.2 L’interface Ada-CGI
Il existe un paquetage [2] pour faciliter l’écriture d’applications CGI en Ada. Ce paquetage a été écrit par David
Wheeler, qui en autorise l’utilisation sans aucune restriction1 du moment que l’on n’oublie pas de mentionner que
c’est lui qui l’a écrit... ce qui est fait maintenant.
A priori, la seule chose réellement nécessaire pour
écrire un programme CGI est la faculté de récupérer la valeur d’une variable d’environnement. En pratique, il faut
analyser la chaîne pour séparer les différentes paires
Clé=Valeur et décoder les espaces et les encodages
hexadécimaux. Ce sont ces services qui sont fournis par
le paquetage CGI, ainsi que des utilitaires facilitant la
production de l’HTML en sortie.
valeurs de tous les paramètres (pour la mise au point),
et la fonction Get_Environment permet de récupérer la valeur de n’importe quelle variable d’environnement.
Une dernière remarque : si ce paquetage ne représente
pas une quantité de travail énorme, il est bien utile en affranchissant le programmeur de toute la partie fastidieuse
du décodage des paramètres. De plus, c’est un bon exemple d’utilisation des nouvelles fonctionnalités Ada 95 de
manipulations de chaînes de caractères.
2.3 UnCGI
Une autre façon de simplifier le décodage des paramètres CGI est d’utiliser UnCGI [3]. Ce programme agit
comme un pré-processeur qui décode les associations
Clés/Valeurs, crée des variables d’environnement portant
le nom des clés, puis appelle un programme utilisateur...
qui peut être écrit en Ada, comme dans n’importe quel
autre langage.
La spécification complète du paquetage est donnée en
annexe 1. Noter que tous les sous-programmes produisant
des chaînes de caractères sont doublés pour retourner soit
des String, soit des Unbounded_String. Les principales fonctionnalités fournies sont :
Pour être honnête, cette interface est surtout utile avec
les langages de script, pour lesquels il est plus simple
d’accéder aux variables d’environnement que de faire des
entrées/sorties.
1) La gestion des paramètres. Les différentes fonctions
Value permettent de récupérer la valeur associée à
une clé (le paramètre Index désignant l’occurrence
de la clé voulue, celle-ci pouvant apparaître plusieurs
fois). Les fonctions Key_Exists pemettent de savoir
si une clé est présente, et Key_Count le nombre
d’occurrences. Il est également possible (fonctions
Key et Value) de connaître la clé (et la valeur associée) se trouvant à une position donnée dans la liste.
Le nombre total de paramètres est fourni par la fonction Argument_Count.
2) La
production
d’HTML.
La
procédure
Put_CGI_Header permet de fournir la première
ligne d’en-tête. Les procédures Put_HTML_Head et
Put_HTML_Tail impriment les début/fin standard de
document HTML. La procédure Put_HTML_Head
sort un texte sous forme de titre standard (balises Hn,
avec n=1 par défaut). Enfin la procédure
Put_Error_Message génère une page complète
contenant un message d’erreur.
3) La gestion des lignes. Une valeur de paramètre peut
s’étendre sur plusieurs lignes. La fonction
Line_Count donne le nombre de lignes dans une
valeur, et la fonction Line_Count_Of_Value donne
le nombre de lignes d’une valeur associée à une clé.
De même, les fonctions Line et Line_Of_Value permettent de récupérer la nième ligne d’une chaîne, ou
d’une valeur associée à une clé.
4) Des fonctions de plus bas niveau. La procédure
Put_Variables imprime (sous forme HTML) les
3 Les applets Java
1
En particulier, sans les restrictions de la licence GPL.
Contrairement au CGI, les applets permettent d’exécuter des programmes sur l’ordinateur du client, c’est à dire
sur la machine qui demande l’affichage de la page Web.
C’est surtout utile pour faire des animations, ou des interfaces plus sophistiquées que ce qu’autorise l’HTML standard.
Le fournisseur d’une page HTML ignorant tout de la
machine qui l’affiche, il fallait définir pour les applets un
format exécutable indépendant de toute architecture matérielle. Java définit donc une machine virtuelle, exécutant un code machine appelé Byte-code. Une applet n’est
donc physiquement qu’une référence à un fichier contenant du byte-code. Lors du chargement de la page, ce
code est transmis à un interpréteur (interne au browser)
qui l’exécutera. L’interpréteur aura la charge de contrôler
le code téléchargé, et en particulier de limiter ou d’interdire des fonctionnalités qui pourraient être dangereuses
pour la machine sur laquelle il s’exécute, comme d’effacer ou modifier des fichiers locaux !
Noter que la machine virtuelle Java est multi-tâche, ce
qui est très utile pour réaliser des animations. Toutefois,
les fonctionnalités de synchronisation et de communication offertes restent très élémentaires, comparées aux possibilités d’Ada.
Sun, qui est à l’origine de Java, a développé un langage
spécifique, le langage Java, et fournit un compilateur traduisant ce langage en byte-code. Ce compilateur fait partie d’un ensemble de composants, le JDK (Java
Development Kit), qui est téléchargeable gratuitement
[4]. Le langage Java est purement orienté objet, c’est-à-
dire que tout est défini sous forme de classes, et que, à part
quelques types (très) élémentaires, toutes les entités manipulées sont à sémantique de référence. Cet aspect est
particulièrement déroutant pour les développeurs habitués à des langages conventionnels, et conduit à d’importantes inefficacités, notamment dans les manipulations de
tableaux.
Un des intérêts de Java est le grand nombre de classes
fournies avec l’environnement, qui permettent de développer des interfaces sophistiquées, de jouer de la musique, d’établir des liaisons internet, etc. On notera
cependant que les classes de base résident sur la machine
hôte ; comme les fonctionnalités ont été rajoutées progressivement dans les différentes versions de l’environnement, les plus récentes d’entre-elles (et souvent les plus
intéressantes) risquent de ne pas fonctionner avec les
browsers les plus anciens, ce qui impose de se limiter si
l’on veut que les applets fonctionnent partout.
3.1 Principe de fonctionnement des applets Java
Une applet devant fonctionner dans une page HTML
est un objet appartenant à une classe dérivée de la classe
Applet. Cette classe fournit un certain nombre de méthodes, dont certaines devront être en général redéfinies. On
trouve ainsi Paint, qui est chargée de redessiner le contenu de l’applet, méthode appelée par le browser à chaque
fois qu’il est nécessaire de remettre à jour l’écran ; init,
qui permet d’initialiser l’applet, appelée par le browser la
première fois que la page est chargée ; start et stop,
appelées par le browser respectivement lorsque la page
devient visible ou est cachée, ce qui évite de laisser "courir" des animations lorsqu’elles ne sont pas visibles ; enfin destroy, qui doit libérer les ressources utilisées, qui
est appelée par le browser lorsque la page disparaît définitivement.
JGNAT n’ayant pas encore été diffusé à la date d’écriture de ces lignes, nous donnerons juste quelques indications concernant la technologie Intermetrics. Une classe
Java correspond à un paquetage Ada contenant la déclaration d’un type étiqueté dont le nom doit obligatoirement
être celui du paquetage auquel on ajoute "_Obj". A part
cela, il s’utilise comme n’importe que type étiqueté. Attention toutefois à un piège : Java dépendant des majuscules/minuscules, il faut que le nom du paquetage donné
en tête de spécification respecte exactement la mise en
majuscule de la classe Java.
Toutes les classes Java ont été interfacées et sont disponibles depuis Ada. Il existe également un paquetage
Interfaces.Java qui assure la compatibilité des types
de données et facilite la correspondance entre chaînes de
caractères Java et Ada. Grâce à cela, il n’est pas plus difficile d’utiliser les classes Java que n’importe quelle autre
bibliothèque pour laquelle un binding Ada a été défini.
Noter également que le compilateur produit des classes compilées absolument standard, et qu’il est donc possible d’utiliser des classes écrites en Ada depuis
n’importe quel programme écrit en langage Java.
3.3 Exemple d’Adapplet
A titre d’exemple, nous fournissons en annexe 2 une
petite applet en Ada qui affiche un menu déroulant contenant des pages web à choisir, et un bouton pour provoquer
l’affichage de la page désirée. Une fois intégrée dans une
page HTML, l’effet produit est le suivant :
3.2 Ecriture d’applets Java en Ada
A priori, rien n’impose un langage particulier pour
produire le byte-code ; il existe un grand nombre de compilateurs pour des langages variés (118 selon [5]) qui génèrent du byte-code au lieu de code natif, y-compris
plusieurs assembleurs. Cela ne présente pas de difficulté
théorique, il ne s’agit en fait que de compilateurs croisés
ayant la machine virtuelle Java pour cible.
En particulier, il est possible de générer du byte-code,
et donc d’écrire des applets, à partir d’Ada1. Cela a été
réalisé par la technologie AppletMagic d’Intermetrics [7]
(aujourd’hui Averstar), que l’on retrouve dans les compilateurs basés sur ce frontal, notamment le compilateur
Aonix [8]. Plus récemment, une version spéciale du compilateur GNAT (nommée JGNAT) a été développée pour
la machine Java par ACT [9].
1
Nous proposons d’appeler les applets écrites en Ada des "Adapplets". Voir la page qui leur est consacrée sur le site Adalog [6].
Dans cette applet, on a juste redéfini la méthode Init
qui met en place les éléments (menu déroulant, bouton) et
la méthode action qui définit les traitements à effectuer
en cas d’évènement concernant l’applet. Remarquer la
présence d’un opérateur unaire "+" qui transforme les
chaînes Ada en chaînes Java.
Des exemples d’Adapplets librement réutilisables (y
compris une version plus évoluée de celle-ci) sont disponibles depuis la page des composants Adalog [10].
4 L’accès à Internet depuis Ada
Le dernier volet des applications possibles de Ada
dans le monde de l’Internet concerne le développement
d’applications utilisant Internet, telles que des logiciels
de courrier électronique, des browsers, des transferts de
fichiers, etc. La problématique particulière à Internet,
pour de telles applications, se trouve évidemment dans
l’interfaçage avec le réseau.
4.1 Les ANC (Ada Network Components)
Il s’agit d’un ensemble de paquetages développés à
l’ENST qui fournissent une interface avec les sockets qui
constituent l’inteface système normale avec le réseau.
Ces composants sont sous licence GPL "assouplie" (modèle de la bibliothèque GNAT), et sont disponibles depuis
[11]. Cette interface peut être qualifiée de "moyenne" (ni
mince, ni épaisse) dans la mesure où le typage a été adapté à Ada, mais où les fonctionnalités fournies correspondent exactement à l’interface socket du système.
Nous donnons à titre d’exemple, en annexe 3, la spécification du paquetage Sockets.
4.2 AdaJNI
Le JNI (Java Native Interface) est une interface permettant d’exécuter du code Java depuis un programme en
C (ainsi, d’ailleurs, qu’inversement). Cela revient, en
gros, à incorporer dans le programme une machine virtuelle, et à lui faire exécuter le code des classes Java que
l’on souhaite utiliser.
La société Ainslie-Software [12] vend une interface
appelée AdaJNI qui fournit les mêmes services à des programmes Ada. Il devient ainsi possible d’utiliser tous les
services de la riche bibliothèque Java depuis un programme Ada natif. En particulier, la bibliothèque Java comporte de nombreuses classes d’interface avec le réseau, ce
qui en fait une alternative intéressante pour l’écriture
d’applications Internet portables.
gnements à ce sujet peuvent être obtenus depuis l’excellent site AdaPower [15], ou la fameuse "page Ada" de
Pascal Obry [16].
Et n’oubliez pas que si vous avez eu un besoin qui
vous a conduit à créer une nouvelle interface avec une bibliothèque existante, d’autres pourraient bien avoir le
même besoin... Pensez à mettre votre travail à disposition
sur Internet ; de nombreux sites sont prêts à héberger le
fruit de vos efforts !
6 Conclusion
Les mêmes outils sont aujourd’hui disponibles pour
développer des applications Internet avec Ada qu’avec
les autres langages. On doit cet (heureux) état de fait aux
nouvelles facilités d’interfaçage apportées par Ada 95, et
au développement de l’Internet lui-même, qui permet de
mettre le travail de chacun à disposition de tous.
Même pour ce type d’application, où le C est traditionnellement utilisé, l’alternative est disponible ; le choix du
langage doit donc être guidé par les critères habituels de
génie logiciel, maintenance, etc. Encore faut-il savoir, et
faire savoir, que le choix existe !
Webliographie
[1] CGI : http://hoohoo.ncsa.uiuc.edu/cgi
[2] Ada-CGI : http://goanna.cs.mit.edu.au/~dale/cgi/cgi.htm
[3] UnCGI : http://www.midwinter.com/~koreth/uncgi.html
[4] JDK : http://java.sun.com/products/jdk/1.2/
[5] Langages pour la Java machine : http://grunge.cs.tu-berlin.de/~tolk/vmlanguages.html
Il existe également une version "libre" de l’interface
Ada-JNI, appelée Café1815 [13], mais elle est actuellement en version Alpha. A suivre...
[6] Adapplets: http://pro.wanadoo.fr/adalog/adapple1.htm
5 Et si cela ne suffit pas...
[9] ACT :http://www.act-europe.fr
Si malgré tout les outils précédants ne répondent pas à
vos besoins, rappelons qu’il est possible d’utiliser en Ada
n’importe quelle bibliothèque interfacée avec le langage
C.
L’adaptation d’une bibliothèque C peut être grandement facilitée par l’utilisation de l’outil C2ADA [14] qui
traduit (presque) automatiquement un fichier d’en-tête C
(".h") en spécification Ada. Il est également possible
d’utiliser des services fournis sous forme de DLL ou
d’utiliser l’interface COM de Microsoft ; tous les rensei-
[7] AppletMagic : http://www.appletmagic.com
[8] Aonix : http://www.aonix.fr
[10] Composants Adalog : http://pro.wanadoo.fr/adalog/
compo1.htm
[11] Ada Network Components : http://www.inf.enst.fr/ANC
[12] Ainslie Software : http://www.ainslie-software.com
[13] Café 1815 : http://www.acenet.com.au/~gbull/
[14] C2ADA : http://www.inmet.com/~mg/c2ada/c2ada.html
[15] AdaPower : http://www.AdaPower.com
[16] Pascal Obry : http://ourworld.compuserve.com/homepages/pascal_obry/ada.html
Annexe 1 : spécification du paquetage CGI
with Ada.Strings.Unbounded;
use
Ada.Strings.Unbounded;
package CGI is
-- This package is an Ada 95 interface to the "Common Gateway Interface" (CGI).
-- This package makes it easier to create Ada programs that can be
-- invoked by World-Wide-Web HTTP servers using the standard CGI interface.
-- CGI is rarely referred to by its full name, so the package name is short.
-- General information on CGI is available at "http://hoohoo.ncsa.uiuc.edu/cgi/".
-- Developed by (C) David A. Wheeler ([email protected]) June 1995.
-- This is version 1.0.
-------
This was inspired by a perl binding by Steven E. Brenner at
"http://www.bio.cam.ac.uk/web/form.html"
and another perl binding by L. Stein at
"http://www-genome.wi.mit.edu/ftp/pub/software/WWW/cgi_docs.html"
A different method for interfacing binding Ada with CGI is to use the
"Un-CGI" interface at "http://www.hyperion.com/~koreth/uncgi.html".
------
This package automatically loads information from CGI on program start-up.
It loads information sent from "Get" or "Post" methods and automatically
splits the data into a set of variables that can be accessed by position or
by name. An "Isindex" request is translated into a request with a single
key named "isindex" with its Value as the query value.
-------
This package provides two data access methods:
1) As an associative array; simply provide the key name and the
value associated with that key will be returned.
2) As a sequence of key-value pairs, indexed from 1 to Argument_Count.
This is similar to Ada library Ada.Command_Line.
The main access routines support both String and Unbounded_String.
-- See the documentation file for more information and sample programs.
function Parsing_Errors return Boolean;
function Input_Received return Boolean;
function Is_Index
return Boolean;
-- An "Isindex" request is turned into
-- with Value(1) as the actual query.
-- True if Error on Parse.
-- True if Input Received.
-- True if an Isindex request made.
a Key of "isindex" at position 1,
type CGI_Method_Type is (Get, Post, Unknown);
function CGI_Method return CGI_Method_Type;
-- True if Get_Method used.
-- Access data as an associative array - given a key, return its value.
-- The Key value is case-sensitive.
-- If a key is required but not present, raise Constraint_Error;
-- otherwise a missing key's value is considered to be "".
-- These routines find the Index'th value of that key (normally the first one).
function Value(Key : in Unbounded_String; Index : in Positive := 1;
Required : in Boolean := False) return Unbounded_String;
function Value(Key : in String; Index : in Positive := 1;
Required : in Boolean := False) return String;
function Value(Key : in Unbounded_String; Index : in Positive := 1;
Required : in Boolean := False) return String;
function Value(Key : in String; Index : in Positive := 1;
Required : in Boolean := False) return Unbounded_String;
-- Was a given key provided?
function Key_Exists(Key : in String; Index : in Positive := 1) return Boolean;
function Key_Exists(Key : in Unbounded_String; Index : in Positive := 1) return Boolean;
-- How many of a given key were provided?
function Key_Count(Key : in String) return Natural;
function Key_Count(Key : in Unbounded_String) return Natural;
-- Access data as an ordered list (it was sent as Key=Value);
-- Keys and Values may be retrieved from Position (1 .. Argument_Count).
-- Constraint_Error will be raised if (Position < 1 or Position > Argument_Count)
function Argument_Count return Natural;
-- 0 means no data sent.
function Key(Position : in Positive) return Unbounded_String;
function Key(Position : in Positive) return String;
function Value(Position : in Positive) return Unbounded_String;
function Value(Position : in Positive) return String;
-- The following are helpful subprograms to simplify use of CGI.
function My_URL return String; -- Returns the URL of this script.
procedure Put_CGI_Header(Header : in String := "Content-type: text/html");
-- Put CGI Header to Current_Output, followed by two carriage returns.
-- This header determines what the program's reply type is.
-- Default is to return a generated HTML document.
procedure Put_HTML_Head(Title : in String; Mail_To : in String := "");
-- Puts to Current_Output an HTML header with title "Title". This is:
-<HTML><HEAD><TITLE> _Title_ </TITLE>
-<LINK REV="made" HREF="mailto: _Mail_To_ ">
-</HEAD><BODY>
-- If Mail_To is omitted, the "made" reverse link is omitted.
procedure Put_HTML_Heading(Title : in String; Level : in Positive);
-- Put an HTML heading at the given level with the given text.
-- If level=1, this puts: <H1>Title</H1>.
procedure Put_HTML_Tail;
-- This is called at the end of an HTML document. It puts to Current_Output:
-</BODY></HTML>
procedure Put_Error_Message(Message : in String);
-- Put to Current_Output an error message.
-- This Puts an HTML_Head, an HTML_Heading, and an HTML_Tail.
-- Call "Put_CGI_Header" before calling this.
procedure Put_Variables;
-- Put to Current_Output all of the CGI variables as an HTML-formatted String.
function Line_Count (Value : in String) return Natural;
-- Given a value that may have multiple lines, count the lines.
-- Returns 0 if Value is the empty/null string (i.e., length=0)
function Line_Count_of_Value (Key : String) return Natural;
-- Given a Key which has a Value that may have multiple lines,
-- count the lines. Returns 0 if Key's Value is the empty/null
-- string (i.e., length=0) or if there's no such Key.
-- This is the same as Line_Count(Value(Key)).
function Line (Value : in String; Position : in Positive)
return String;
-- Given a value that may have multiple lines, return the given line.
-- If there's no such line, raise Constraint_Error.
function Value_of_Line (Key : String; Position : Positive)
return String;
-- Given a Key which has a Value that may have multiple lines,
-- return the given line. If there's no such line, raise Constraint_Error.
-- If there's no such Key, return the null string.
-- This is the same as Line(Value(Key), Position).
function Get_Environment(Variable : in String) return String;
-- Return the given environment variable's value.
-- Returns "" if the variable does not exist.
end CGI;
Annexe 2 : Exemple d’applet Java en Ada
-------------------------------------------------------------------------------- Adapplet filesel
--- (C) Copyright 1998 ADALOG
-------------------------------------------------------------------------------with Java.Lang, Java.Applet.Applet, Java.Awt.Event;
use Java.Lang, Java.Applet.Applet;
-- Clauses for private part only:
with Java.Awt.Button, Java.Awt.Choice;
package filesel is
type Filesel_Obj is new Applet_Obj with private;
procedure init
(Obj
function action (Obj
Evt
What
return Boolean;
:
:
:
:
access Filesel_Obj);
access Filesel_Obj;
Java.Awt.Event.Event_Ptr;
Object_Ptr)
private
use Java.Awt.Button, Java.Awt.Choice;
type Filesel_Obj is new Applet_Obj with
record
Download_Button : Button_Ptr;
Format_List
: Choice_Ptr;
end record;
end filesel;
with Java.Awt.Component, Java.Awt.Color;
with Java.Applet.AppletContext;
with Java.Net.URL;
with Interfaces.Java; use Interfaces.Java;
package body filesel is
procedure init (Obj : access Filesel_Obj) is
use Java.Awt.Component, Java.Awt.Color;
Junk : Component_Ptr;
begin
setBackground (Obj, new_Color(255, 255, 128));
Obj.Format_List := new_Choice;
addItem (Obj.Format_List, +"index.htm");
addItem (Obj.Format_List, +"adapple1.htm");
Junk := add (Obj, +"WEST", Component_Ptr (Obj.Format_List));
Obj.Download_Button := new_Button (+"Afficher");
Junk := add (Obj, +"EAST", Component_Ptr (Obj.Download_Button));
Validate (Obj);
end Init;
function action (Obj : access Filesel_Obj;
Evt : Java.Awt.Event.Event_Ptr;
What : Object_Ptr)
return Boolean
is
use Java.Net.URL, Java.Applet.AppletContext;
begin
if Evt.Target = Object_Ptr (Obj.Download_Button) then
showDocument (getAppletContext(Obj),
new_URL (getDocumentBase(Obj),
getSelectedItem (Obj.Format_List)));
end if;
return True;
end action;
end filesel;
Annexe 3 : Spécification du paquetage Sockets (ANC)
-------------------------------------------------------------------------------ADASOCKETS COMPONENTS
----S O C K E T S
----S p e c
----$ReleaseVersion: 0.1.3 $
----- Copyright (C) 1998 École Nationale Supérieure des Télécommunications ----AdaSockets is free software; you can redistribute it and/or modify
--it under terms of the GNU General Public License as published by
--the Free Software Foundation; either version 2, or (at your option)
--any later version.
AdaSockets is distributed in the hope that it
--will be useful, but WITHOUT ANY WARRANTY; without even the implied
--warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.
--See the GNU General Public License for more details. You should
--have received a copy of the GNU General Public License distributed
--with AdaSockets; see
file COPYING. If not, write to the Free
--Software Foundation, 59
Temple Place Suite 330, Boston, MA
--02111-1307, USA.
----As a special exception, if other files instantiate generics from
--this unit, or you link this unit with other files to produce an
--executable, this unit does not by itself cause the resulting
--executable to be covered by the GNU General Public License. This
--exception does not however invalidate any other reasons why the
--executable file might be covered by the GNU Public License.
----The main repository for this software is located at:
--http://www-inf.enst.fr/ANC/
--------------------------------------------------------------------------------
with Ada.Streams;
with Interfaces.C;
package Sockets is
type Socket_FD is tagged private;
-- A socket
type Socket_Domain is (AF_INET);
-- AF_INET: Internet sockets (yes, should be PF_INET, but they hold the
-- same value)
type Socket_Type is (SOCK_STREAM, SOCK_DGRAM);
-- SOCK_STREAM: Stream mode
(TCP)
-- SOCK_DGRAM: Datagram mode (UDP, Multicast)
procedure Socket
(Sock
: out Socket_FD;
Domain : in Socket_Domain := AF_INET;
Typ
: in Socket_Type
:= SOCK_STREAM);
-- Create a socket of the given mode
Connection_Refused : exception;
procedure Connect
(Socket : in Socket_FD;
Host
: in String;
Port
: in Positive);
-- Connect a socket on a given host/port. Raise Connection_Refused if
-- the connection has not been accepted by the other end.
procedure Bind
(Socket : in Socket_FD;
Port
: in Positive);
-- Bind a socket on a given port
procedure Listen
(Socket
: in Socket_FD;
Queue_Size : in Positive := 5);
-- Create a socket's listen queue
type Socket_Level is (SOL_SOCKET, IPPROTO_IP);
type Socket_Option is (SO_REUSEADDR, IP_MULTICAST_TTL,
IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP,
IP_MULTICAST_LOOP);
procedure Setsockopt
(Socket : in Socket_FD'Class;
Level
: in Socket_Level := SOL_SOCKET;
Optname : in Socket_Option;
Optval : in Integer);
-- Set a socket option
generic
Level
: Socket_Level;
Optname : Socket_Option;
type Opt_Type is private;
procedure Customized_Setsockopt (Socket : in Socket_FD'Class;
Optval : in Opt_Type);
-- Low level control on setsockopt
procedure Accept_Socket (Socket
: in Socket_FD;
--
New_Socket : out Socket_FD);
Accept a connection on a socket
Connection_Closed : exception;
procedure Send (Socket : in Socket_FD;
Data
: in Ada.Streams.Stream_Element_Array);
-- Send data on a socket. Raise Connection_Closed if the socket
-- has been closed.
function Receive (Socket : Socket_FD;
Max
: Ada.Streams.Stream_Element_Count := 4096)
return Ada.Streams.Stream_Element_Array;
-- Receive data from a socket. May raise Connection_Closed
procedure Receive (Socket : in Socket_FD'Class;
Data
: out Ada.Streams.Stream_Element_Array);
-- Fill data from a socket. Raise Connection_Closed if the socket has
-- been closed before the end of the array.
type Shutdown_Type is (Receive, Send, Both);
procedure Shutdown (Socket : in Socket_FD;
How
: in Shutdown_Type := Both);
-- Close a previously opened socket
---------------------------------- String-oriented subprograms ---------------------------------procedure Put (Socket : in Socket_FD'Class;
Str
: in String);
-- Send a string on the socket
procedure New_Line (Socket : in Socket_FD'Class;
Count : in Natural := 1);
-- Send CR/LF sequences on the socket
procedure Put_Line (Socket : in Socket_FD'Class;
Str
: in String);
-- Send a string + CR/LF on the socket
function Get (Socket : Socket_FD'Class) return String;
-- Get a string from the socket
function Get_Line (Socket : Socket_FD'Class) return String;
-- Get a full line from the socket. CR is ignored and LF is considered
-- as an end-of-line marker.
private
....
end Sockets;
Ada and the Internet:
Information Linking, Agents
and the scale of the Web
Scott Arthur Moody
Impact Systems
Seattle, Washington, USA
[email protected]
1. Web Surfing and Ada 95
Web “Surfing” has been used to describe how people interact
with the internet. Having seen and participated in real surfing and
wind surfing, I would have to say that the excitement factors are
vastly different, favoring the real thing. But global accessibility
aside, how can those of us that really enjoy distributed
technologies also get as excited about the web?
Enter the late 1990’s and the re-introduction of the Ada
Language (Ada 95) now combined with an array of powerful
support tools (many GNU based). Harnessing the Web can now
be enhanced by using the powerful computing paradigms
supported by Ada. One can get all the benefits of the traditional
uses of a high performance and portable computing language
(including debugger support) - combined with the ubiquitous
interfaces provided through the Web.
This presentation seeks to show some exciting uses of Ada and
the Internet, especially uses of concurrent and distributed
capabilities to cope with the scale possible with successful web
ventures, and uses of web server tools such as Apache. “RealTime”, the other part of this weeks excellent conference is
appropriate in context, since the web can challenge any
architecture and implementation as the many real-world issues
sneak in. This can range from the technical aspects such as
millions of web-hits, or continuous operation with no down time,
or vast intranets behind the firewalls of important institutions.
Then solving something mundane like maintaining and changing
the software through every aspect of the development cycle where cycles are definitely at the “speed of the internet”.
1.1
Enter Ada 95 and the Web
Now take Ada 95 - still a relatively unknown language - one
might ask how could it compete with the “true” languages of the
web such as Perl and Java, or the server language C++? I think
the answer to this lies in how the “internet” is defined. If one
looks at the simple to complex web interfaces, tools like Perl and
Java are appropriate. But look past this thin layer of webinterfaces. There could be an entire factory production line
running or a host of distributed servers interfaces to distributed
databases, or robots sending commands for visibility through the
web, or maybe items in your home letting you know their status
(i.e. getting low on food, everything is ok, baby sleeping, being
robbed, etc.). The point being that the web and the internet are
just one aspect of todays vast computing infrastructure.
1.2
Paper Outline
This paper will highlight some specific concerns with privacy
and consumer use of the internet. A new web addressing concept
is introduced called a Digital Address. These digital addresses
Ada and the Internet - Ada France 1999
are shown to support privacy with the added value of allowing
subscription and publishing of consumer information (once
privacy concerns are addressed). The architecture of “agents”,
implemented in Ada, is shown along with a user access method
of the Web, using an Apache server and embedded perl web
content creation. Issues with “internet scale” are highlighted combined with some solution techniques.
2. Privacy and Spam Internet Concerns
As an introduction to the application of Ada described in this
paper, two specific issues with consumer use of the web need to
be highlighted. In particular, consumer privacy and unwanted
‘spam’ email.
Privacy is the #1 concern on the Internet today. This has
been widely acknowledged in recent studies, including the May
24, 1999 special edition of The Industry Standard (http://
www.thestandard.net/metrics/display/0,1283,897,00.html). In
particular this study noted that despite the fact that 66% of
“.com” Web sites now post a privacy policy (vs. 4% one year
ago), fear of spam (unsolicited commercial email) has actually
increased to the point where 63% of Internet users (47.2M
people) now fear getting spam from any online purchase.
Spam is the most serious invasion of privacy for most
Internet users. Spam has always been a serious problem for the
Internet—by 1997, roughly one-third of the email message traffic
AOL carries on any given day was spam. Now sophisticated new
email address harvesting and bulk mailing programs are
accelerating the problem. Almost 50 percent of e-mail users say
they get spammed six or more times a week, according to a
recent study of 13,000 e-mail users conducted by the Gartner
Group. Infrequent email users whose email address lands on a
spam list find that as much as 80% of their email is spam. And
changing one's email address is only a temporary solution until
the new address is harvested by spammers.
2.1
Product and Concept Solutions
In an attempt to solve the privacy and spam concerns, a Seattle
Internet company, Intermind 1 , has developed and patented a
powerful new solution to Internet privacy. Intermind's U.S.
patent #5,862,325, issued January 19, 1999, is the first patent in
World Wide Web Consortium (W3C) history to be the subject of
a press release seeking prior art (May 3, 1999). The W3C
acknowledges it covers the essential elements of P3P (Platform
for Privacy Preferences), a standard the W3C began developing a
year after the patent was filed.
1. Thanks must be given to Drummon Reed, from Intermind and author of the
pattents, for providing information on the digital address and privacy concepts.
1 of 5
August 22, 1999
The patent covers a breakthrough solution for spam—the
digital privacy filter. A digital privacy filter works identically to
the caller ID-based telephone privacy filters now being sold by
all the major telcos, including Ameritech, GTE, US West, etc.
With these filters, unrecognized callers (i.e., callers whose caller
ID is not in the user's "accept" list, or who have caller ID
blocked) are intercepted by a message saying this number does
not accept solicitations. Solicitors are asked to hang up; other
callers can press "1" to get through (or leave a message for
further screening).
A digital privacy filter is "caller ID for email". Installed either
at the client (for POP3 email) or server (for IMAP or Web-based
email), the filter compares each incoming message to the
recipient's "accept" list (see the attached diagram). However
unlike crude filters which simply delete messages from
unrecognized senders, making email communications from new
contacts all but impossible, a digital privacy filter sends a privacy
message back to unrecognized senders. This message contains a
link to the receiver's digital address agent—a Web server which
displays the receiver's personal privacy rules to which the sender
must agree in order to gain access to the receiver's email address.
Although the receiver can customize these rules in any way, the
most common standard rule is, "I do not accept unsolicited
commercial email."
Digital privacy filters are the first "killer app" for digital
address service. Just as the telco's new privacy services are all
based on caller ID, digital privacy filters are based on digital
addressing. A digital address is a new type of address that
combines all other types of addresses—email addresses, Web
addresses, postal addresses, telephone numbers, fax numbers,
etc.—into a single "smart" address for all digital
communications. This is very similar to capability based
systems[6]
2.2
History of Addressing
Evolution of addresses:
• 1800’s : delivery addresses (postal, parcel,telegraph)
• 1900’s : telecom addresses (phone, fax, pager, cell)
• 1980’s : email addresses (DNS names, IP addresses)
• 1990’s : Web addresses (URL, URI)
• 2000+ : Future Digital Addresses
New addressing would be the same "abstraction layer" on top
of any type of communications control data. An "active address"
that can be associated with a resource. These addresses are
objects with properties and methods; a platform for the active
linking of information.
One key drawback to the Web today is that links are passive,
eg. they are designed to only transfer data when manually
activiated by people. The next phase in the evolution of network
com munica tions is for links to be come ac tive, e g. to
automatically exhchange information when specified events
occur at either end of the link.
2.3
Digital Addresses for Privacy
Although privacy protection is the breakthrough benefit that
will ignite initial demand for digital address service, digital
addresses are a fundamental technological advance creating an
entire "platform" for new products and services, much as the
transition from character-based interfaces to graphical user
interfaces created a new platform for personal computer
applications. The benefits of the digital address platform include:
H yp er-tex t
N a vigation
A u tom atic Info
A gent u p d ates
A G E N T m a na ged L in k D atab ase(x)
S u b scriber(i)
P u b lish er(a)
d igital
ad d ress
p rivacy
filters
S u b scrib er(j)
L in k D atab ase(y)
P u blish er(b )
Tran sform a tion
Figure 1.
Persistent and Dynamic Link Management
A digital address can be as simple as a name or
phrase, in any language, so it is extremely easy to
remember. To convey the simplicity and power of an
address it can simply be your name (the only special
syntax might be a leading "@" sign, e.g., @Bill
Clinton, @Microsoft, @Gone With The Wind, etc.)
• A digital address never has to change for the
lifetime of its owner, no matter how often its owner
changes email addresses, postal addresses, phone
numbers, etc.
• Digital addresses dramatically simplify data
exchange. With an XML-based protocol (a superset
of P3P), digital agents can automate the exchange of
any data stored in the owner's digital profile. For
example, users can literally "beam" contact data
over the Web into other user's address books in one
step. And using XML, profiles can be extended to
cover any type of digital data, from email addresses
to encryption keys to pizza preferences.
• Digital address books can automatically
synchronize data updates. Change any item of
your digital profile—such as an email address or
phone number—and the digital address book of
every contact with whom you have linked that data
will be updated automatically.
Digital addresses support powerful new directory services.
Using XML-based digital profiles, aliasing, and other
architectural features, digital addresses will make it an order of
magnitude easier for consumers and businesses to find each
other.
Digital addresses are particularly compelling for Internet
mailing lists. Not only do they automatically assure list
subscribers of the privacy of their email address, but they
eliminate bounces due to bad email addresses by automatically
sending a change-of-address message to the list server whenever
the user changes a subscribed address. Intermind has confirmed
the appeal of these advantages with several of the largest Internet
discussion lists including Topica and SkyList, and has entered
into letters of intent with TibBITS, one of the oldest and most
influential Internet newsletters, and MessageMedia, one of the
largest Internet email service bureaus with a volume of over 25M
messages a month.
•
2 of 5
SimpleGraphics
Dynamic Web Page Creation
modperl
Tcl/Tk/Blt
Perl
External
Addressing
PHP
SWIG
coupling
Personal Agent
Link Agent
Agent (core)
Tree Addressing
XML Tree Management
Database Engines
Figure 2.
Schema
Rules
The architecture developed to manage the digital address and
the user management of their published and subscribed
information is shown in Figure 2. The “agent” is run as a server
Visualization
Apache Web Server
httpd deamons
P3P Privacy
Rules
3. Agents and the Web
process managing the users’ persistent information sources. The
agent architecture is built through object hierarchies so additional
capabilities can be added.
In particular, the architecture supports “plug-in” rule
processing. This is where a users’ P3P privacy rules, and other
notification and data rules are inserted. The core agent manages
these plug-ins, but also manages all XML tree manipulation.
Rules Processing
2.4
Digital Addresses and Scaling for the Web
Since todays web involves “passive link network”, the next
phase will be a global platform for the active linking of
information, or an “active link network”. Designing a new
generalized address agent service, must include:
• human friendly syntax
• internalization (unicode)
• large flat top-level namespace
• extensible
• privacy protection
• active linking/caching
The general architecture for management of bi-directional
information management is shown in Figure 1. Publishers and
Subscribers interact with each other by using their digital
addresses which is controlled by their “agents”. Agents will
manage the users’ privacy concerns while also keeping
information content consistent.
Without going into more implementation detail, the following
high level questions must still be addressed:
• How specifically will a digital addressing
architecture distribute the load so the top-level
namespace can support billions of names?
• Given the much higher write activity of digital
address/data agents than conventional directory
entries, how can we make sure these writes are not a
bottleneck?
• How will the distributed architecture efficiently
handle queries and update messages between digital
address/link servers as the system scales to tens and
then hundreds of millions of names?
• Are there specific architecture choices that will
support faced increase of digital address names over
internet time?
These are difficult questions but using high level toolsets that
include concurrency and distribution, such as Ada, one can get a
lot of real experience and architectural flexibility to deal with
these scaling issues. “Distribution” makes for more exciting use
of the internet and intranet, or at least lets users explore many
runtime architectures without being tied to a single ‘web’ based
interface.
The typical web design supports returning static web content
to users. A typical architecture uses a number of httpd web
servers running on the same host, and when the scale increases,
to add more host computers and load-balance requests to a nonbusy host and a free httpd process.
A very popular server is from Apache and has heritage in the
original NCSA servers. FreeBSD is also extremely popular
because of it’s network support (and another reason for Ada
GNU support on FreeBSD).
Traditionally, this architecture is a relatively static web
application - which is then complicated by the vast scale. But as
this application gets more difficult - say managing data in a
database, or performing autonomous actions on your behalf such as a proxy or agent - the existing computing bottlenecks are
pushed past the web front-ends and into the “intranet” of your
application domain.
File Systems (XML)
Agent Architecture
Once outside the core agent, a number of added capabilities
are required. The architecture is designed so the “web” is the not
the primary interface. In fact, the web interface is just one of the
ways to access the information. The goal is that testing of the
agent server can be done at every level. This allows developers to
leverage their power-tools, such as debuggers and runtime
printouts. Debugging using the web is a non-trivial process.
Some of the architecture issues include:
• Accessibility of information (ui, web, palm pilots,
tcl/tk, etc) - since the various access mechanisms
keep growing, the architecture must support
changing of interfaces easily.
• Privacy and Notification capabilities, and how they
would be added. It would be great if seamless ‘filter’
insertion (like the GLADE encryption filters) were
used.
• Scaling (through processes), including issues such
as fault-tolerant agent-to-process servers, possibly
using a multi-cast capability.
• Information ‘transport’ issues - how does the
information get passed between the various users
(eg. http(s), xml(rpc/http), CORBA, GLADE,
JavaRMI)
• Personalization and programming of the agents and
dealing with future agent mobility (eg. agent
programming languages[1]).
The Ada real-time toolset, including full object oriented
features, concurrency, distribution and other “real-time” features
are all needed to help solve these issues.
3 of 5
4. Apache, Perl and Ada
Providing web accessibility to the agents was still one of the
most important capabilities needed. This requires connection to a
web server and providing a dynamic web content generation
capability. Given the architecture described above, this had to be
connected in some manner to the web - and then eventually
support the scaleup desired.
Dynamic web content generation is traditionally done from
inside the web-server running with the Apache server, there are
two good ways to get pre-loaded functionality:
• Embedded Perl - where perl code is actually
embedded inside HTML code. Execution can be
increased since an Apache deamon will pre-load
various parts of the perl code. Unfortunately, for
development, the web code is hard to manage
especially if using power HTML generation tools.
• PHP - is a “C” like interface that is also embedded
inside the HTML code. The advantage is that non
perl programmers are happy, and the interface to a
“C” server layer is one-to-one.
The agent server, developed in Ada, then needed to be
integrated to the web-content generation code. We figured this
had to be possible, assuming we could get it to work through
Apache and run on the machines of interest - FreeBSD and
Linux. Thus there had to be some good interfacing mechanisms.
Ada is about the only language I know that has a whole annex on
how to “interface” to other languages. Also there is a standard
way for the executable not to take over the “main” of the
application, by providing initialization routines (try to do this
with C++ in a portable manner).
4.1
SWIG Interfaces between Ada and Perl
The Perl and C community have developed a number of
interfaces between themselves, in particular the SWIG interface.
SWIG takes a “C” header (.h) file and generates a Perl interface.
Once an interface is made to “C”, we know that Ada can easily
interface. So this system incorporates a thin layer of Ada to Perl
via a SWIG “C-to-Perl” interface layer (actually SWIG is similar
to marshaling/demarshling code since it actually converts a “char
*” to a Perl string - and passing an Ada address via “char *”
won’t convert correctly back to the address of the native
language.) Then as the power of the Ada server is increased, the
layer of Perl interfacing to the web can be decreased.
For those that like Tcl/Tk - an equally powerful (or more
powerful) web capability that could rival Java/Perl is also
available - except for it’s obscurity and the non-pre-loaded
plugins for tcl/tk in the common web browsers.
Once the server was integrated, we had another “agent” testing
option - the Web. Not relying only on this capability for testing
helps ensure the integrity of the entire product. This is especially
true with the Web, since errors are very unforgiving. In
particular, errors will usually crash the web server, and
debugging (using gdb) is very difficult. Also, any new
capabilities requires taking down the web-server, relinking, and
restarting. This can be difficult in an already running system.
The other main advantage of using a high-level object-oriented
language, like Ada, for the web server is efficiency. For example,
the partial Ada XML parser and agent server would compile and
link faster than the Perl+XML parser would run.
4.2
Concurrency and then Distribution for Scale
As the architecture is expanded to handle the scale desired,
practicing the various distributed interfaces will be crucial. Ask
yourself how are you going to be sure the connectivity choices of
the distributed application are correct or working? It would make
sense to test these distributed interfaces in advance of full-scale
deployment. Without a simple, or nearly seamless, language
mechanism in support - which Ada 95 provides, it is harder for
others in the computing field without these tools, to proceed. One
reason is that they haven’t practised enough using current tools,
before jumping in the deep-end of web-distributed.
Development options for building the “distributed interfaces”
vary, but can evolve in the following order, starting with the
easiest to build and test.
• build object interfaces and start testing in the same
program.
• add threads to model concurrency
• use “seamless” distributed objects in Ada, to model
real distribution
• then can start building different external interfaces,
including c-interface (maybe for the web) or IDL
interfaces
• Or soon can convert parts of the application to Java
and interface that way.
An ASIS assisted tool could also help build interfaces based
on the current state of the user’ software. This could also help
generate the SWIG interfaces.
4.3
Addressing using XML
One of the goals of this project is to provide the digital
addressing protocol in an “open-source” manner. Use of XML
(eXtensible Markup Language) was chosen. It has many
strengths especially if passing information throughout the web.
In the XML internet world - there are a host of capabilities.
These include DOM - the document object model, which
includes a set of common API’s for traversing XML trees. These
interfaces are useful, but getting past the retrieval of information
from a tree, to the updates and management of that information,
one must go deeper into the object definitions and control. This
includes creation of class structures and then methods, refined
operations, inherited capability - all the fundamentals of Object
Oriented programming and programming languages.
Management of the subscription and publishing information
must have total traceability so when changes are made, the
correct subscribers are updated. Thus we determined that a full
addressing schema was necessary (since any depth of object
could be addressable).
For manipulation of the XML tree structure, a new Tree
Arithmetic and addressing was defined. This is basically a “dotpath”, and can be seen the individual nodes of Figure 3. Since the
nodes in the software are first-class addressable objects, new
types were defined for addressing and all nodes have primitive
methods returning their address. The other benefit was that since
copying and pointing to existing data is such a common
operation, copying sub-trees around between agents was needed.
This involves copy and then re-numbering sub-trees. But the
unique nature of the addressing made it possible to only change
the root address, and keep the same tail address. It became very
easy to test and debug tree manipulation software when code
looked as easy as:
new_address := old_address - old_root + new_root
4.4
Visualization of XML Trees
Visualization of complex software applications is an exciting
and challenging field. Useful displays are invaluable for
developers in analysis of their software systems, and for
meaningful system presentations to customers at a higher
conceptual level. This was applied to visualization of XML trees.
4 of 5
Advanced visualization techniques combined with adaptable
and extensible software architectures can help support
manageable rapid application development. Looking at the tree
normal compile-link-run language). By using Ada, and the new
JGNAT (Ada to Java GNU/GNAT) capability, an Ada web server
developer has an inexpensive Java entry for breaking past the
java-or-not barrier.
Now specific portions of an existing and tested application can
be converted with no new code development. Looking at the
agent and XML processing presented here, if a more “client”
based web client is needed - this can be easily achieved. This is
what we call a “local-agent”. In this specific case, if XML was
sent to a client, the specific rule processing must still be
performed. These rules are already codified in the Ada server
processing. This same processing must be done by the client, so
it makes sense to ship the actual code - thus shipping in Java
would be attractive.
It will be exciting to see all the uses of JGNAT as this new
capability is released and widely used.
6. Future Work
Figure 3.
Agent XML tree representations
in Figure 3., one sees the publisher/subscriber relation expanded
into real data exchanges. In this implementation, using Tcl/Tk/
Blt and the multi-threading of Ada, interesting and semi
animated visuals of the trees are achieved. (Also using tasks/
threads in a SimpleGraphics[5] framework, allows the graphic
itself to have response time while the animation takes place.)
Now what happens if the complexity of these links is increased
ten fold, or more? Viewing that complexity will be difficult in
2D. So something like cone_trees, a 3D tree animated directory
tree could be useful[2]. I cannot show or justifiably describe the
animation achieved by Robertson, et al - in their vintage 1991
Cone Trees, and other 3D spacial views. But the most important
feature is that their animation allows the user to keep the context
of items that are leaving the field of view (moving to the hidden
part of the tree) - but knowing they are moving away while other
data is coming into view. Saving this context is of great value.
Small changes, iterations, or gradual change, these help us cope
with complexity.
There is still a lot of design and real-experience needed to
satisfy the scalability concerns. The next step is to handle the
dynamic access of already executing “agent servers”. Some type
of dynamic object registry is needed, one that can manage
running or cached objects somewhere in the intranet. This seems
an ideal use for the “shared-passive” Ada language feature especially if a multi-cast capability were implemented. There are
still language issues since distributed Ada objects cannot be
placed in “pure” partitions. Maybe the replication is not of the
objects themselves, but the location of distributed servers?
Another concern is that Ada isn’t an accepted language and
where will programmers who know Ada be found? Then what
about the “open-source’ community - won’t your tool look bad if
the software is done in that rogue language, Ada, instead of Perl?
Hopefully after enough real internet experiences are published,
these concerns will be decreased. This will be especially true
when the concurrency, distribution and real-time attributes are
shown to be important for complex internet applications.
In closing, I think its appropriate when talking with todays
internet, to also think back to pioneers as far back as we can
remember, but in our domain we can go back to our languages’
namesake: Augusta Ada Byron (1815 - 1852). Reading about her
life and the “computer” concepts she understood is exciting[4].
I’m sure she would have relished first the telegraph (also called
the Victorian Internet[7]) and then the real internet.
References
[1]
S. Moody, “STARS Process Engine: Agents Artifacts and
Activities”, TriAda 94.
[2]
Robertson, et al. “Cone Trees: Animated 3D Visualization of
Hierarchical Information”. Proceedings SIGCHI 91.
[3]
M. Harrison, Tcl/Tk Tools, O’Reilly, 1997
[4]
B. Toole, Ada: Enchantress of Numbers, Strawberry Press, 1992/
98, http://www.well.com/user/adatoole
5. Java and Ada - JGNAT
[5]
S. Moody, et al. “Simple Graphics”, IRTAW-99, Ada Letters, June
99.
Java adds another dimension to the web architectures. Mostly
Java is used for web ‘client’ programs - albeit very large. As
agent processes get more complicated, code mobility will be
useful. This is where Java would be very useful.
Currently developers must decide to develop their application
in Java or another language. Thus their flexibility is hindered in
some ways by Java. In particular, interfacing other technologies
and languages with Java has been difficult (Java isn’t your
[6]
H. Levy, Capability-Based Computer Systems, Digital Press, 1984
[7]
T. Standage, The Victorian Internet, Walker Publishing Company,
1998
More information on Impact Systems can be found at their
web page: http://WhiteRiverRanch.com/impacts
5 of 5
CIAO
Opening the Ada 95 Distributed Systems Annex to CORBA Clients
Thomas Quinot
École nationale supérieure des télécommunications
46, rue Barrault
F-75643 PARIS CEDEX 13
France
E-mail: [email protected]
Abstract
tion. No code specific to distribution needs to be written;
the distributed application uses exactly the same native Ada
data types as a non-distributed ones; local procedure calls
are simply converted by the compiler to remote invocations.
When an abstraction is made remote, no modification of its
clients is required.
CORBA [4], a set of industry standards promoted by the
OMG consortium, is based on OMG IDL, a descriptive language whose syntax is close to C++, which is used to describe the services provided by a class of objects. IDL specifications can be mapped to different host languages such as
C++, Ada 95, Java, or SmallTalk. A service developed in
C++ can thus be accessed by clients written in Ada or Java,
that run on entirely different platforms. The OMG has also
standardized the protocols that are used for inter-node communication, theoretically allowing interoperation between
products developed using tools from different vendors.
While the Distributed Systems Annex of Ada 95 provides
developers with a framework for easy contruction of safe
distributed systems, integrating distribution seamlessly in
the strong typing and well-defined semantics of Ada, it lacks
the cross-platform, multiple-languages capabilities offered
by CORBA.
This paper presents CIAO (CORBA Interface for Ada
distributed Objects), a tool for automated generation of
proxies that allow CORBA clients to interact with services
created using the Distributed Systems Annex. A representation of DSA service specifications in OMG IDL is first
presented. We then describe an automated translation tool
based on this representation model. This tool is based on
ASIS, a standardized API for the extraction of syntactic
and semantic information from an Ada compilation environment. It uses Broca, a full Ada ORB developed at ENST.
CIAO and Broca are to be released as Free Software in the
forthcoming months.
1
1.1
1.2
The CIAO project
We have provided an in-depth comparison of the Distributed Systems Annex and CORBA in [5]. Our team has
been researching solutions to take advantage of the safety of
the annex, as well as of the emphasis put on code reuse and
good software engineering practice by Ada, while opening
distributed services to the multiple platforms and languages
supported by CORBA. We have thus started the implementation of CIAO (CORBA Interface for Ada distributed Objects), a tool for automated generation of proxies between
DSA services and CORBA clients. We see the development
of CIAO as an opportunity to promote the use of Ada 95 as a
competitive platform for the creation of distributed services.
The principle of CIAO is to first generate an IDL specification that represents a service created using the distributed
systems annex, and then automatically generate an implementation of this CORBA contract. In sections 2 and 3, we
Introduction
The Distributed Systems Annex and CORBA
The Distributed Systems Annex of the Ada 95 standard [2] provides application developers with a framework
for easy construction of distributed systems. It integrates
distribution as a natural extension of the language’s abstraction paradigm. This allows applications developed using
the annex to get the full benefits of the strongly typed programming model of Ada; the debugging of such applications is made very easy as well, because one can first write
a system as a non-distributed, traditional Ada program, then
later partition it and transform it into a distributed applica1
present a method and tool for the translation of a DSA service specification to IDL. In section 4, we then describe the
automated implementation generator, and in section 5 we
discuss the operation of the generated implementation.
with the Pure category can also intervene in a service specification, because the Annex allows a Remote Types or Remote Call Interface to depend on a Pure unit.
2.2
2
2.1
Service specifications in
distributed systems
Specification of CORBA services
The CORBA distributed programming model is more restrictive than the one of DSA. It is purely object-oriented:
any service in a CORBA system is described in terms of
objects that implement interfaces. The description of an interface, its associated data types and its operations together
constitute an IDL specification. An IDL to host language
translator is used to produce client stubs and server skeletons for the object. The generated stubs and skeletons depend on a particular Object Request Broker (ORB, the runtime component that implements the CORBA protocols)
implementation. The mapping of IDL constructs to host
languages is standardized by OMG. In the case of Ada 95,
the mapping does not make use of the distributed systems
annex; the IDL base data types are mapped to specific Ada
types declared in a standard CORBA package, and object
references are mapped to private tagged types that extend
a root CORBA.Object.Ref type. Distribution is thus apparent and intrusive, because it is necessary to explicitly obtain
object references in a CORBA-specific way, and to convert
data types between the mapped IDL types and their native
Ada counterparts.
Specification of DSA services
In Ada 95, abstraction between the interface (or specification) and implementation of a service (i. e. a set of
data types and operation signatures) is provided by packages. The declaration of a package can contain, in particular, the declaration of data types and subprograms, while
the body of the package contains the implementation of the
subprograms. This imposes a clear specification of a functional module’s interface, and a complete separation between specification and implementation.
The Distributed Systems Annex (DSA) naturally extends
this model by allowing the programmer to specify that the
interface defined by a specific package declaration is to be
considered “remote”: several pragmas allow the definition
of a category on a package, which indicates to the compiler
that subprogram calls are potentially to be executed on remote hosts, and that objects declared using the types defined
in the package may also reside on other nodes.
The Remote Types pragma is used to define potentially
distributed object types. When a tagged limited private
type (e. g. type Foo is tagged limited private) and a corresponding class-wide access type (type
Foo Ref is access all Foo’Class) are declared
in a Remote Types package, then an instance of (a derived
type of) Foo that resides on a given node can be designated by a Foo Ref value held on another node: such an
access type is called a remote access to class-wide type
(or RACW). A node that has a RACW which designates
a remote object can invoke methods on that object; these
method invocations are serviced using a remote procedure
call performed by the Partition communication Subsystem
(PCS), which is completely hidden within the compiler’s
run-time library. To the programmer’s eyes, the behaviour
of his application is exactly as though the object instance
lived within the same process.
The Remote Call Interface allows the creation of pure
remote procedure call servers. When a library unit is categorized using that pragma, the Ada partitioning tool guarantees that the package is instantiated on exactly one node,
and any call to a subprogram defined in that package made
from any partition is treated as a remote call as well.
The specification of a service in the DSA thus consists in the declaration of a package that has the Remote Types or Remote Call Interface category. Packages
2.3
Formal mapping of DSA specifications into
OMG IDL
In order to open access to DSA services for CORBA
clients, we first have to represent the interface of such a service in CORBA’s specification paradigm. In other words,
we have to translate the declaration of a DSA package into
an IDL specification. To this effect, we have defined in
[6] a complete formal mapping of such declarations into
OMG IDL. That document precisely defines the translation
of all legal DSA declarations into IDL abstract trees.
The translation starts with the root Ada non-terminal,
compilation unit. A compilation unit is mapped to an IDL
<module>; subunits are mapped to nested modules. The
declarations in a compilation units are likewise mapped to
IDL declarations. More generally, the translation of an Ada
construct is specified as an equivalent IDL element. When
this element is a non-terminal of the IDL grammar, we then
have to specify how its sub-elements are to be constructed.
We give this construction in terms of the translations of
other Ada elements, and thus recursively define a translation for all valid constructs that can be encountered in a
DSA package declaration.
Most Ada types are mapped to their “natural” IDL counterparts: numeric, enumerated, boolean, and string types are
2
translated to the corresponding IDL constructs. Ada records
are translated to IDL struct types. The members of that
structure type are the respective translations of the component declarations of the Ada record. Variant records are represented using structures and unions, and arrays are represented as sequences.
Some Ada types have semantics that are inherently local
to the node that created them. This is the case, for example, for non-remote access types, as well as limited types.
The Distributed Systems Annex mandates that such a type
shall have user-defined marshalling and unmarshalling subprograms if they are to be used in the specification of a DSA
service. In the CORBA translation of a service, these types
are represented as opaque sequences of octets. A CORBA
client can thus obtain a value of those types, and send it
back unchanged to a DSA server.
Potentially distributed objects are declared in Ada as
tagged limited private types. Such a type is mapped to an
IDL interface declaration. The methods of this interface are
translated from the declarations of the Ada type’s primitive
operations. Since the “self” parameter of object methods
(which designates the object instance that is the target of
the call) is implicit in IDL, we omit the first controlling formal parameter of all primitive declarations for distributed
object types.
We have thus defined a complete translation of all legal
Ada constructs in OMG IDL. The only exceptions are renaming declarations and generic instantiations. These are
not taken into account in the current translation, because
they introduce complex visibility and name resolution problems; we therefore decided to concentrate on getting a first
operational version of the translation without these constructs.
3
are built in the compiler; it provides an easy access to the
syntax tree and associated semantic information built by the
compiler from a compilation unit.
ASIS standardizes a set of queries that allow an Ada program to manipulate the syntactic information corresponding to another Ada program: for a given Ada element, it
gives access to its children element; a systematic recursive
traversal iterator is provided, as well as queries that allow
the user to explicitly obtain specific children elements of an
element. These are the ASIS syntactic queries. A set of
semantic queries is also defined. These functions provide
information about the semantic relationships between elements. For example, from an element that is a usage name
for an entity, they can provide the definition of that entity.
We thus can view ASIS as a reflexivity interface for Ada.
The CIAO DSA to IDL translator uses ASIS. This makes
it independent of any particular Ada compilation environment, although it is developed primarily with the GNAT
compiler, and the associated ASIS-for-GNAT implementation. GNAT [8] is a free software Ada compilation environment initially developed at New-York University and now
maintained by Ada Core Technologies1 .
3.2
3.2.1
Overview
The CIAO Translator [7] uses ASIS to extract syntactic and
semantic information from the GNAT Ada 95 compilation
environment. The program is easily portable to any other
compilation environment that supports ASIS, for it does not
depend on compiler internals, but only on some utility libraries that come with GNAT in source form.
The operation of the translator has two main phases. The
Ada semantic tree is first recursively traversed using the
standard ASIS iterator, ASIS.Traverse Element. This is a
generic iterator that provides a framework for a systematic
recursive, depth-first traversal of an Ada syntax tree. The internal state of the traversal functions includes the IDL syntax tree being constructed, as well as a “current position”
pointer designating a node in the tree. When an Ada element is encountered that must be translated, a new node
is created and becomes the current node. The children of
the Ada element are then explored, either explicitly using
ASIS syntactic queries, or implicitly as a result of the continuation of the iterator. When an element is processed, its
translation is attached as a subnode of the current node.
When the whole Ada tree has been explored, we have
an in-memory image of an IDL abstract tree. This tree gets
decorated with semantic information, to allow the implementation generator to obtain sufficient information about
Implementing an Ada to IDL translator
Having established a model for the translation of DSA
service descriptions into OMG IDL specifications, the
CIAO project continued with the development of a translator that implements this model. In this section, we first
present a standard library for Ada CASE tool construction,
then discuss the implementation of our DSA to IDL translator using that library.
3.1
The CIAO translator
The Ada Semantic Interface Specification
ASIS [3] (Ada Semantic Interface Specification) is an
open, published, vendor-independent API for interaction
between CASE tools and an Ada compilation environment.
It defines the operations needed by such tools to extract information about compiled Ada code from the compilation
environment. The ASIS interface allows the tool developer
to take advantage of the parser and semantic analyser that
1 See
3
http://www.gnat.com/.
package Gizmos is
pragma Remote_Types;
Ada 95 syntactic
and semantic information
CIAO application
type Root_Gizmo is
abstract tagged
limited private;
CIAO translator
subtype Celsius is Float
range −273.15 .. Float’Last;
type Price is digits 5;
OMG IDL syntax tree
type Gizmo_Params is record
Temperature : Celsius;
Cost
: Price;
end record;
CIAO generator
IDL
Impl
procedure Heat
(Self: access Root_Gizmo;
How_Much : in Celsius);
function Get_Params
(G: in Root_Gizmo)
return Gizmo_Params;
OMG IDL source text
IDL to Ada translator
(AdaBroker)
Proxy packages
CORBA server skeleton
type Electric_Gizmo is
new Root_Gizmo with private;
function Is_Plugged_In
(Self: access Electric_Gizmo)
return Boolean;
CORBA server implementation
Figure 1. Flow of information through CIAO
private
−− Private part omitted.
end Gizmos;
the translated DSA service. Once this IDL tree is constructed, a trivial recursive traversal is performed, in order
to produce the corresponding IDL source file. This merely
consists in descending the tree depth-first, emitting a textual
representation of each node as it is traversed into an output
file; see samples 1 and 2 for an example of the translation.
The last phase consists in the generation of the CORBA
implementation. The code generator is driven by the IDL
tree, and uses ASIS queries to retrieve supplementary information about the structure of the DSA service from the Ada
environment. Figure 1 summarizes the flow of data through
CIAO tools.
3.2.2
Sample 1: Example DSA package Gizmos
Translator uses numerous ASIS queries to obtain the descriptions of the Ada elements to be translated. Some of the
Ada tree is simply traversed according to the default depthfirst traversal provided by the standard iterator. On the other
hand, for some particular elements, this default systematic
traversal is inappropriate. Some parts of the Ada tree are
to be ignored in the translation. For example, the private
part of a DSA package declaration does not define a service
provided by that package to exterior clients, and is therefore not translated. Similarly, the “self” formal parameter
of distributed object methods is implicit in IDL, and must
be omitted. In these situations, we explicitly use ASIS syntactic queries to explore the Ada tree, and bypass the default
traversal.
We also make use of semantic queries, most notably for
the resolution of entity usage names. The ASIS implementation has access to the Ada abstract tree as constructed and
decorated by the compiler. All the name resolution and visibility rules are thus already applied; from any usage name,
we can immediately obtain the corresponding defining oc-
Construction of the IDL tree
The overall structure of CIAO is presented on figure 2. The
main procedure, Driver, initializes the ASIS environment,
then schedules the different translation and code generation
phases.
The first phase consists in the production of the IDL
abstract tree from the DSA package declaration. This is
the responsibility of the Translator package. This package essentially contains an instantiation of the generic Traverse Element iterator, and defines the function that maps
an Ada element into its IDL translation, as defined by the
formal translation model.
4
Functional blocks
#include "ciao.idl"
CIAO.Driver
module CORBA__Gizmos {
interface Root_Gizmo;
typedef double Celsius;
CIAO.Translator
typedef double Price;
typedef struct
Gizmo_Params_struct
{
Celsius Temperature;
Price Cost;
} Gizmo_Params;
CIAO.ASIS_Queries
CIAO.Generator
IDL
Impl
CIAO.IDL_Syntax
Asis
CIAO.IDL_Tree
Ada 95 compilation environment
OMG IDL syntax tree
interface Electric_Gizmo;
interface Root_Gizmo
{
void Heat
(in Celsius How_Much);
Gizmo_Params
Get_Params ();
};
Figure 2. Structure of CIAO
the nodes using a higher-level package, IDL Syntax, which
enforces the IDL grammar rules. Each node also includes
semantic flags, as well as a pointer to the original Ada element. This attribute is essential for the implementation
generator, because it establishes a “bridge” between the semantics of the IDL contract and that of the DSA service.
interface Electric_Gizmo
: Root_Gizmo
{
boolean Is_Plugged_In ();
};
};
4
The implementation generator
Sample 2: Generated IDL for Gizmos
The next step in the CIAO processing is the generation
of an implementation for the constructed IDL specification.
Using a standard IDL to Ada compiler, the source file created by the translator can be mapped to CORBA client stubs
and server skeletons. The skeleton for an interface contains the declaration of an abstract tagged type whose primitive operations correspond to the methods of the interface.
The server developer must then produce an implementation type, which extends the skeleton type and overrides its
primitives with actual implementations.
In the context of a CORBA to DSA proxy, these actual
implementations must convert the parameters of the method
invocation from CORBA mapped types to native Ada types
(which are used in DSA calls), then perform a DSA remote
call and possibly convert back a return value.
For CIAO, we have produced a code generator that automatically creates the implementation for interfaces generated by the translator described above. These implementations are targeted to the Broca CORBA toolkit, a
free software ORB and IDL-to-Ada compiler developed at
ENST [1]. As Broca implements CORBA’s Portable Object Adapter, there is very little code in CIAO that actually
currence, and thus the denoted entity.
The translator needs to know of some high-level semantic properties that are defined in the language reference
manual, but have no corresponding ASIS queries. For example, in order to translate a subprogram declaration in a
Remote Types package and associate it with the proper IDL
interface, its controlling formal parameters have to be determined. To address this requirement, we have created a set
of “extended” ASIS queries that correspond to properties
formally defined in the Ada standard, and we have isolated
them in a package (ASIS Queries) that can be reused independently of the CIAO project in any ASIS tool that would
need access to these properties.
We have also designed a library for manipulation of IDL
abstract trees. We based it on existing components for syntax tree data types: this library is an adaptation of parts of
the GNAT compiler, which were modified to handle IDL
nodes rather than Ada nodes. Like the original, this library has two layers. IDL Tree provides low-level access
to a “universal” node structure. Other packages only access
5
depends on the ORB implementation, and we consider the
generated code to be fairly portable to another CORBA implementation.
This generator is driven by the IDL abstract tree, because
the structure of the produced code corresponds to the layout
of the IDL specification as a set of nested modules of interfaces. Semantic information from the Ada environment
is also used for the construction of the necessary parameter
type conversions, constraint checks, and DSA method invocations. Indeed, a lot of semantic information is lost during the translation of DSA specifications to IDL; IDL has a
far less expressiveness, and cannot represent such concepts
as subtypes or constrained types. Consequently, the code
generator uses annotations inserted in the IDL tree by the
translator that point back into the Ada tree, and uses ASIS
to complete the code production.
The generator also produces conversion packages for
data types that are declared in the DSA packages: when
a native DSA type is translated to IDL, the mapped type
used by the IDL to Ada compiler is different from the original type. For example, an Ada String, translated to an
IDL String, will be mapped back as a CORBA.String.
We therefore produce subprograms to convert data back and
forth between the two type sets. These functions are used in
the generated implementations to convert the call arguments
and return values.
5
5.1
RACW
CORBA bus
Partition 1
Partition 2
DSA object
CORBA
DSA object
2. Mapped DSA call
Client
Application
CORBA glue
1. CORBA call
ORB
Proxy partition
Figure 3. Calling DSA objects from CORBA
(37.0), a CORBA request is sent to the proxy partition’s
ORB. The ORB looks up the IOR in its internal tables, and
calls the Heat method on the CORBA implementation object for interface Gizmo. This method first checks that the
provided actual for parameter How Much satisfies the constraint on subtype Celsius. The implementation object has
an internal variable which is a RACW Self Access designating the actual DSA object. After the constraint check is
made, the Heat subprogram uses this RACW to perform a
dispatching call to Heat (Self Access, 37). This call may or
may not be remote, depending whether the user has chosen
to affect the proxy package on the partition where the DSA
object instance was created.
The run-time operation of the proxy
Execution of calls
5.2
For each DSA package, we have automatically generated a CORBA skeleton package, using Broca’s IDL to Ada
compiler, and a matching implementation package, using
the CIAO code generator. These packages together constitute a “proxy” that acts as a gateway between CORBA
clients and DSA servers.
Using a partitioning tool such as Gnatdist, the user can
then assign the proxy packages onto a partition in her DSA
application. That partition is then linked with the Broca
run-time library, and behaves as a CORBA server. It may
receive requests from CORBA clients; these requests are
serviced by calling the generated implementation subprograms, which in turn call the original DSA operations. The
structure of such a distributed application is summarised on
figure 3.
Suppose for instance that a CORBA client has obtained
a CORBA object address (an IOR, Interface Object Reference) My Gizmo that designates a DSA object of type
Gizmo’Class. The type of this IOR is the CORBA mapped
interface Gizmo. As far as CORBA is concerned, it designates some object that is managed by the ORB on the proxy
partition. When the client makes a call to My Gizmo.Heat
Creation of object references
We have discussed the operation of the proxy from the
point where CORBA clients have obtained IORs that designate DSA objects; we still need to provide a mechanism for
assigning an IOR to a DSA object.
For this purpose, we take advantage of the Portable Object Adapter facility integrated in Broca. In a CORBA system, the Object Adapter (OA) is the software component
that implements the management of the entities that incarnate CORBA Objects, and enforces policies over their creation, activation, deactivation and destruction. In former
CORBA versions, only one OA existed: the Basic Object
Adapter (BOA). In the BOA, exactly one unique implementation object exists for each CORBA object reference. The
POA introduces much more flexibility in the design of a
server: it allows a server to contain only one implementation object for a whole class of CORBA objects; within a
method invocation, standard function calls to the ORB provide a way to identify the specific instance which is the
target of the call, using a user-assigned identifier which is
embedded in the object reference.
CIAO uses this policy for the implementation of interfaces that represent Ada distributed objects. The object
6
identifier that we chose is simply the marshalled form of
a RACW (a DSA object reference) that designate the object. Each time one such reference is to be transmitted to
a CORBA client, we construct an IOR by associating that
object identifier with the POA created at initialization time
by the proxy for the class of the object. There is no need to
register that newly-created IOR with the ORB, thus avoiding any run-time memory leak. Since the RACW can be
computed back from the IOR, there is no need to maintain a
record of the mapping between DSA objects and IORs: the
proxy is stateless, and can be stopped and restarted without
loss of functionality in case of a fault.
The POA thus permits the creation of CORBA object references that correspond to RACWs. Remote Access to Subprogram types can designate distributed subprograms; these
are conceptually equivalent to objects with no attributes,
and with a single operation, Invoke. We can thus treat RAS
types likewise, as a particular form of object references, and
handle them in a similar fashion to RACW types, once more
using the marshalling and unmarshalling functions provided
by the Annex.
Remote Call Interface packages are much simple to handle; since each RCI package is instantiated only once in a
complete DSA application, only one object reference for its
CORBA implementation object is needed. In the case of
RCIs, the POA is thus used in its mode of operation that is
closest to the BOA: a single implementation object is created, and it is activated and assigned a reference by the ORB
at proxy start-up.
5.3
CIAO proxy
3. Forwarded call
4. Return DSA object ref.
RCI package
1. Register RCI interface
4. Forwarded
return value
CORBA Naming Service
3. Call RCI
2. Provide reference to RCI
RCI has a DSA reference
RT package
CORBA client
5. Client can invoke
method on object
Distributed object instance
Figure 4. Bootstrapping a CIAO application
terface; the proxy packages automatically registers the corresponding objects with the CORBA naming service at
start-up time. In this scheme, CORBA clients can obtain
references to the RCI packages by querying the CORBA
Naming service, and then request objects from RCI servers
just like normal DSA clients. We thus naturally transport
the DSA model of operation into the CORBA world, by
making the procedure for getting initial references to RCI
packages explicit (whereas it is implied in DSA).
An example of this protocol is given on figure 4. If the
application was purely based on DSA, then at startup a node
would only be able to make remote calls to the RCI package. This is how it would obtain references to objects that
live on other partitions. When the CIAO proxy is started,
it creates a CORBA implementation object for the interface
of the RCI package, and registers a reference to this object with the CORBA naming service (1). A CORBA ORB
provides a method by which a CORBA client can obtain
an initial reference to the naming service. The client can
then query the naming service and obtain the reference to
the RCI package (2). This reference is used to perform a
remote call on the RCI package (3), which finally returns a
reference to a DSA object (4). The CORBA client can thus
invoke a method on the DSA object (5) just as any DSA
node could.
Initial distribution of references
In distributed systems, initially obtaining a distributed
object reference may be difficult. It is often necessary to
query a distributed naming service to obtain object references, but it is impossible to use the naming service to retrieve its own root reference. In DSA, an object reference
can only be created when a value is transported (as a remote
call parameter, or as a remote function return value); when
an object is created on a partition, the only way for a client
partition to obtain a reference to that object is to get it as a
value returned by a remote call, i. e. as the return value or
as an out mode parameter of a RCI or RAS call, or RACW
primitive operation call.
Initially, clients always obtain their first object reference
using RCI calls, because RCI have a fixed, well-know position within the distributed application; the Partition Communication Subsystem includes its own “hidden” mechanism for name resolution, and initially provides a means for
any partition to make a call to any RCI package.
In CIAO, we have thus decided to solve the “chicken
& egg” problem in the following way: RCI packages are
mapped to modules with a single Remote Subprograms in-
6
Conclusion
The Distributed Systems Annex provides a superior
framework for the development of safe distributed applications. It is well-integrated in the Ada software engineering practice, and allows for an easy transition from nondistributed to distributed code. CORBA, on the other hand,
emphasises interoperation between objects created and residing on different platforms, written using different languages, and different CORBA implementations.
7
We proposed a solution to make the best of both worlds:
the tools presented here allow a CORBA client to access
services provided by DSA objects and servers. It makes use
of ASIS, an ISO standardized API for Ada CASE tools. It
is based on free software components developed by ENST
and others, and will be made freely available in source code
in the near future.
References
[1] T. Gingold. Broca, an Ada CORBA implementation. Master’s
thesis, ENST Paris, July 1999.
[2] ISO. Information Technology – Programming Languages –
Ada. ISO, Feb. 1995. ISO/IEC/ANSI 8652:1995.
[3] ISO. Information Technology – Programming Languages –
Ada Semantic Interface Specification (ASIS). ISO, 1998.
[4] Object Management Group. The Common Object Request
Broker: Architecture and Specification, revision 2.2. February
1998. OMG Technical Document formal/98-07-01.
[5] L. Pautet, T. Quinot, and S. Tardieu. CORBA & DSA: Divorce or Marriage? In Proceedings of AdaEurope’99, Santander, Spain, June 1999.
[6] T. Quinot. Mapping the Ada 95 Distributed Systems Annex
to OMG IDL — Mapping definition. Technical report, ENST
Paris and university Paris VI, May 1999.
[7] T. Quinot. Mapping the Ada 95 Distributed Systems Annex
to OMG IDL — Specification and implementation. Master’s
thesis, ENST Paris, Aug 1999.
[8] E. Schonberg and B. Banner. The GNAT project: A GNUAda 9X compiler. In Proceedings of Tri-Ada’94, Baltimore,
Maryland, USA, 1994.
8
JGNAT
The GNAT Ada 95
environment for the JVM
Emmanuel Briot
[email protected]
ACT Europe
Summary
GNAT-to-JVM Compiler
Tools, Debugging, Distributed Systems
Interoperability
Mapping Java to Ada
Example: Tic Tac Toe Applet
Anything special about the
Java programming language ?
Java
Language
Ada
Java Virtual Machine
APIs and Libraries
4Java is very Ada friendly
4JVM is an excellent Ada platform
4Java APIs are a fundamental
component of the technology
GNAT to JVM Compiler
ACT has a tradition of ...
4Doing 100% Ada 95 implementations
Ð core language
Ð all Annexes
Ð 100% validations
4Using Ada 95 to develop its products
4Sources available under GPL license
4Implement 100% Ada 95 (core + annexes)
Ð in particular implement all the Ada library
(Ada .Text_IO, ...)
Ð certain features have no impact on generated code
(e.g. some representation clauses, É)
Ð full Real Time Annex compliance if underlying JVM
supports it (thread priorities, É)
4Implemented entirely in Ada 95
4Main design document available
4100% sources available under GPL license
Very Natural Mapping between
Ada 95 & JVM
ADA
scalars
arrays
records
tagged types
packages
subprograms
default initializations
exceptions
JVM
primitive types
arrays
final classes
classes
classes (sometimes packages)
methods
constructors
exceptions
The JVM makes it easy for ...
4No memory layout needed
4Stack machine for computations
4OO model built in
4Exception model built in
4Protected record-like mechanism built-in
4Index checks for free
4Null-dereference checks for free
Extra work needed for
4Deep copy operations (x := y)
4Access to subprograms
4Nested subprograms (static chains)
4Pass slices by copy makes your life simpler
É.
Fortran
Java
C++
C
Front
Ada
ends
GCC
target
machine
code
Backend
target
independent
target
description
x86 PowerPC 68K
MIPS Sparc Alpha
i960 IA-64 HP-PA É
Unix
VMS
NT
OS/2
VxWorks
ÉÉÉ
The GNAT JVM Backend
Ad
a
Ada
GNAT
GIGI
GCC
Ada
GNAT
Jexpand
Machine
code
Java
Code Gen.
bytecode
1. expands some
Ada constructs
GNAT
front-end
2. makes calls to JVM
code generator
Juggler
High-level JVM interface
Low-level bytecode interface
Javelin
Class file
generator
Bytecode
Generator
GNAT JV M back end
1. JVM instruction
selection
2. JVM peephole
optimizations
By
te
co
de
GNAT & Ada 95 Tasking
yo
u r Your code
Ad
a
ap
High-level tasking services
pl
GNARL
i c Gnat runtime
at
io
GNULLI
n
Target independent
Windows NT
OS/2
Solaris
VxWorks
low-level tasking API
GNAT runtime & JVM
Ü
Each Ada task maps onto a
Java thread
Ü
Ada code with tasks can call
Java code with threads &
conversely !
Ü
Lock/unlock map onto JVM
monitor operations
Ü
Task priorities map onto Java
thread priorities, but...
Ü
Most GNULLI primitives map
nicely into JAVA thread ops
Your code
GNARL
JVM
GNULLI
a
d
A
95
e
d
co
GNARL_Op1(..);
GNARL_Op1(..);
GNAT
expander
GNARL_Op2(..);
GNARL_Op2(..);
GNARL_Op3(..);
GNARL_Op3(..);
GNARL interface
Target
independent
GNARL body
GNULL interface
Target
dependent
GNULL body
JVM ops + Java API
Prototype Implementation
4ALL CORE tasking tests passed
(on every pure Java JVM implementation)
4Ada RT Annex Tests:
Ð JDK 1.1.4: several tests failed
Ð JDK 1.1.5: most Annex D tests passed
on Solaris JVM (native threads)
4JGNAT guarantees real-time Ada 95
semantics on JVMs with real-time behavior
Tools
Some JGNAT Tools...
4 jvmstrip
Ð
Strips all debugging info from .class files
4 jvmlist
Ð
Ð
Displays class file contents
Embeds original source into class bytecode
4 jvm2ada
Ð
Ð
produces an Ada spec from any class file
allows transparent use of any Java API from Ada
Other GNAT Tools...
4jgnat, jgnatmake, jgnatbind, jgnatlink
Ð Standard GNAT tools available
4gnatxref, gnatfind, gnathtml
4gnatprep
Ð GNAT preprocessor
4gnatstub
Ð Generate stubbed compilable bodies from specs
4gnatelim
Ð Detect and eliminate unused subprograms on a complete
partition
4 É.
Symbolic Debugging
GNAT leverages
on existing tools
4Any pure Java debugger works with GNAT
4Debugger needs specialization for Ada 95 to
Ð display data in Ada 95 format
Ð understand Ada 95 syntax
Ð switch between Ada tasks conveniently
JVM debugging technology
debugger
JNI
JVM
Debug
API
sockets
Could be same machine
JNDI
your app
JNI
JVM
JNDI = Java Native Debugging Interface
Debugger need not
run on a JVM
De
bu
gg
er
JNDI
JNI
App
JVM
JNDI = Java Native Debugging Interface
De
bu
gg
er
debugging in a
cross environment
sockets
JNDI
JNI
App
JVM
The GNAT Debugger
command parser
output formatter
low-level
debugger
Target dep.
hooks
Distributed Systems
GLADE
GNATÕs Distributed Systems Annex
4Management of communications between Ada
partitions
4Tools to define partition location & content
* Heterogeneous Communication
* Data filtering (encryption, compression)
* Replication Capabilities
* Embedded Capabilities
Ada 95
Distributed Sys Annex
& the JVM
LA
D
E
Ada
E
G
G
LA
D
Ada
J
VM
GLADE
Ada
Interoperability
Java
Language
Ada
Java Virtual Machine
APIs and Libraries
4Java is very Ada friendly
4JVM is an excellent Ada platform
4Java APIs are a fundamental
component of the technology
ACT has a tradition of ...
4Full adherence to platform-specific ABI
¥
¥
¥
calling sequences
object code format
debugging information
4Full interoperability with other languages
4Full access to libraries written in other
languages
Full JVM
Interoperability
This means that ...
4GNAT is highly compatible with existing
JVM tools & environments
4Tools may need specialization for Ada 95
but do not need rewriting
4Full transparent access to Java API
4Full Java interoperability
Ð Access any Java services from Ada
Ð Use Ada services from Java
Ð Ability to extend Java classes or Ada tagged
types across languages
Ð Ability to propagate and catch exceptions across
languages
4New interfacing pragmas
Ð Import/Export (Java,É)/...
Mix and
and match
match
Mix
and Java
Java
AAddaa and
as the
the developer
developer
as
sees fit
fit
sees
Important Remark
Java
Language
Transparent
Ada
Java Virtual Machine
Example: GNAT for Java Demo
Ada
Ada
GNAT
for
Java
Java socket
interface
Java
Bytecode
Ada RT code
Full interoperability
with Java & its API
2 independent
threads
Java
Language
Ada
Java VM
Java API
Java serial port
interface
UI
G
va
Ja
jvm2ada
Java
Language
Ada
Java Virtual Machine
APIs and Libraries
jvm2ada
4100% Java-to-Ada API conversion tool
4Absolutely no manual intervention
4Works on EVERY Java library
4Distribute the tool NOT Ada bindings
4Java-to-Ada mapping works whether Ada
code is on the JVM or on native machine
JVM & the native world
JNI
JVM
API
JNI = Java Native Interface
JVM & Native Interoperability
Java
Language
Ada
same
pragmas
Ada
Ada pragmas
JNI
Java
Language
JVM
API
Other
Language
What about ?same
pragmas
Ada
Other
Language
C, Fortan, É
Ada pragmas
JNI
Ada
JVM
API
Wherever your Ada code runs
Ada
a
d
A
"
s
e
it v ma
a ag
n
" pr
Other
Other
Language
Language
C,
,É
C, Fortan
Fortan,
É
JVM
"n
at
pr ive"
ag A
m da
as
Java
Language
Ada & Java
Interfacing
Summary
4Tool for automated interfacing (jvm2ada)
4Mapping Java classes to Ada packages
4Pragma Import and Convention
4Handling circularities
4Implicit conversions
4Support for Java interfaces
4Mapping Java to Ada
Automated Interfacing to Java
Using jvm2ada
4Using Java APIs from Ada should be easy
4All API functionality must be available
4jvm2ada generates Ada specs from
Ð .class, .zip and .jar files
4No hand-editing of Ada required
4Can map ALL Java classes onto Ada packages
4Handles circularities in Java API classes
4Supports Java interfaces and constructors
Mapping Java Classes to Ada
Packages
4Each Java class is represented by an Ada
library package
4The Ada package contains a single tagged type
with components and primitive operations
4Uses pragmas Import and Convention
4Java-specific pragmas for interfaces and
constructors
4Java packages and nested classes use child
units
Pragma Import and Convention
4Pragma Import (Java, entity_name, [external_name])
Ð On packages (JGNAT maps to a Java class)
Ð On subprograms (JGNAT maps to a Java method)
Ð On variables (JGNAT maps to a static field)
4Pragma Convention (Java, entity_name)
Ð On a tagged type (JGNAT maps to a Java class)
Ð On a subprogram (JGNAT uses Java conventions)
Direct Mappings
4Abstract Classes & Methods
4Static Methods and Static Fields
4Native Methods: pragma Import (C, É)
4Final Fields: constants
4Volatile Fields: pragma volatile
Classes
public class F o o {
public int F i e l d;
public void S o m e _ O p (int p) {É}
static public int V a r;
static public int F u n c (Foo obj, F o o [ ] b) return i n t ;
}
Using FooÕs services in Ada
public class F o o {
public int F i e l d;
public void Some_Op (i n t p) {É}
with Java; use Java;
static public int Var;
with F o o;
use F o o;
o
static public int F u n c (Foo obj, F o o [ ] b)
return int;
procedure Client i s
O b j : F o o.Ref
:= new_F o o;
o
o
A : F o o.Arr
:= new F o o.Arr_ObjÕ(0
.. 9 => 2 2 ) ;
o
o
X : i n t := F o o.F
o u n c (O b j, A);
begin
S o m e _ O p (O b j, X);
O b j.Field := 22;
F o o.V
o a r := 3;
end Client;
with Java.L a n g.Object; use Java.Lang.Object;
package F o o is
type T y p is new Java.L a n g.Object.Typ with record
Field : Integer;
public class F o o {
end record;
public int F i e l d;
type Ref is access all TypÕClass;
public void Some_Op (i n t p) {É}
static public int Var;
type Arr_Obj is
static public int F u n c (Foo obj,
array (Natural range <>) of Ref ;
F o o [ ] b)
type Arr
is access all A r r _O b j;
return int;
procedure Some_Op (This : access T y p; P : Integer);
function new_ F o o (This : Ref := null) return Ref;
V a r : Integer;
function Func (O b j : access TypÕClass;
B : Arr) return Integ e r ;
end Foo;
Handling Circularities
public class Object {
...
public S t r i n g toString ();
}
public final class S t r i n g {
...
public static String valu eOf (O b j e c t o b j) ;
}
with type
with type j a v a.l a n g.String.Ref is access;
package java.lang.Object is
type Typ is tagged limited private;
function toString (This : access Typ) return j a v a.l a n g.String.Ref;
...
end java. l a n g.Object;
with type j a v a.l a n g.Object.T y p is tagged;
with java. l a n g.Object;
package java.lang.String is
type Typ is new java.lang.Object.Typ with null record;
type Ref is access all TypÕClass;
function valueOf (Obj : access j a v a.l a n g.Object.TypÕClass)
return Ref;
end java.lang.String;
Client Code
with Java.Lang.Object;
with Java.Lang.String;
procedure Client is
O b j : java.lang.Object.Ref := ...;
Str : java.lang.String.Ref := toString (Obj) ;
...
Implicit Conversions
4Problem: Java more weakly typed than Ada 95,
making use of access types cumbersome
4Java:
Ð Allows freely passing objects to parent operations
Ð Null may be passed to non controlling arguments
4Ada 95:
Ð Can have many access types (e.g., one per tagged type)
Ð Named access type parameters do not allow implicit
conversions
Ð Access parameters allow implicit conversions, but
restricted in use (null actual causes exception)
Possible Solutions
4Relax Ada rules for passing null to access
parameters (for Java-convention subprograms)
Ð Problem: Not clearly legitimate semantics
4Syntactic GNAT-specific language extensions
Ð Special syntax for "open" access types that allow
implicit conversions
Ð Problem: Non standard extension
4Official language extension as part of with type
Ð Implicit conversions allowed for all general access
types (access all, access constant)
Ð Problem: Might cause ambiguities (incompatibility)
Java Specific Pragmas
4Java_Interface
4Java_Constructor
Java Interfaces
4Java interface types allow a nice form of
multiple inheritance not supported by Ada 95
4A Java class may "implement" multiple
interfaces, inheriting and overriding interface
methods
4Ada tagged types can only extend from a
single parent
4Java API classes depend on interfaces
4Generic mix-ins are a possible mechanism,
but unwieldy
Using Java Interfaces from Ada
4A Java interface is mapped onto an
abstract tagged type with abstract
operations (pragma Java_Interface)
4The tagged type has a single access
discriminant:
type Some_Interface (Self : access Java.Lang.Object'cl a s s) is
new abstract J a v a .L a n g.Object with null recor d ;
pragma Java_Interface (Some_Interface);
4Other tagged types can implement one or
more Java interfaces
4Implementing type overrides operations of
its parent interface types
type Interface_User
(I_Some_Interface : access Some_Interface'class;
I_Other_Interface : access Other_Interface'clas s;
... etc.)
is new Parent_Type with ...;
Java_Interface
with Java.Lang.Object; use Java.Lang.Object;
package F o o is
type Typ (Self : access Object.TypÕClass)
is new abstract Object.T y p with null record;
pragma Java_Interface (Typ);
type Ref is access all Typ'Class;
procedure Proc (This : access Typ; Val : Float) is abstract;
function Func (This : access Typ) return Float is abstract;
end Foo;
Using a Java Interface
with Java.Lang.Object; use Java.Lang.Object;
with F o o;
package Bar is
type Typ (I _F o o : access Foo.TypÕClass)
is new Java.Lang.Object.Typ with record
Field : Integer;
end record;
type Ref is access all Typ'Class;
procedure Proc (This : access T y p; Val : Float);
function Func (This : access T y p) return Float;
end Bar;
Conversions
with Java.Lang.Object; use Java.Lang.Object;
with Foo;
package Bar is
type Typ (I _F o o : access F o o.TypÕClass)
is new Java.Lang.Object.T y p with record
Field : Integer;
end record;
type Ref is access all Typ'Class;
procedure Proc (This : access T y p; Val : Fl o a t ) ;
function F u n c (This : access T y p) return Float;
end Bar;
with Java.L a n g.Object; use Java.L a n g.Object;
package Foo is
type Typ (Self : access Obj e c t .TypÕClass)
is new abstract Obj e c t .T y p with null record;
pragma Java_Interface ( T y p) ;
type Ref is access all Typ'Class;
procedure Proc (This : access Typ; Val : Float)
function F u n c (This : access Typ) return Float
end F o o ;
X : Bar := new Bar.Typ;
Y : F o o.Ref := X.I_Foo; -- OK -conversion allowed, no checks.
Z : Bar.Ref := Foo.Ref (Y.Self); -- At run-time, check that
-- Y points to an object in Bar.Obj'Class
Java_Constructor
public class C {
public int field;
public C ()
{ field = 3; }
public C (i n t i)
{ field = i; }
public C (int I, int j ) { this (I + j); }
}
with Java.Lang.Object;
package C is
type Typ
T y p is new Java.Lang.Object.Typ with record
Field : Integer;
end record;
type Ref is access all Typ'Class;
function n e w _ C (This : Ref := null) return Ref;
function n e w _ C (I : Integer; This : Ref := null) return Ref;
function n e w _ C (I, J : Integer; This : Ref := null) return Ref;
pragma Java_Constructor (new_C);
end C;
package body C i s
function new_C (This : Ref := null) return Ref is
Super : Java.L a n g.Object.Ref := new_Object (Object.Ref (This));
begin
This.Field := 3;
return This;
end new_C;
function new_C (I : Integer; This : Ref := null) return Ref is
Super : Java.L a n g.Object.Ref := new_Object (Object.Ref (This));
begin
This.Field := I;
return This;
end new_C;
function new_C (I, J : Integer; This : Ref := null) return Ref is
Ignore : Ref := new_C (I + J, Object.Ref (This));
begin
return This;
end new_C;
java.lang.Object
with type Java.L a n g.String.Ref is access;
package J a v a .L a n g. O b j e c t is
type T y p is tagged limited private ;
type R e f is access all TypÕClass;
É
private
type T y p is tagged limited null record;
end Java.Lang.Object;
type T y p is tagged lim i t e d
private;
4Java classes are limited types
Ð no object assignment (no deep cop y )
4Warning:
Ð must call a constructor to create an object
(Java semantics)
Ð No stand alone Java object can be created
on the Ada side if there is no default
constructor that the compiler can c a l l
Problem if no default constructor
public class Bar {
public Bar (int i) {É}
É
}
// only constructor
O b j : Bar.Typ; -- ? ? ?
JGNAT:
Walk through a
simple demo applet
Overview
Java Applets vs Applications
Creating a new applet with JGNAT
Compiling and running the Applet
Applet vs Application
4ÒWrite once, execute anywhereÓ
4Executed by a JVM interpreter
4Applet: Embedded in a Web browser.
Ð Security restrictions
4Application: Independent program
Ð Full access to the Java API
Applets (1)
4Extends the
java.applet.Applet class
Called by the browser to
this HTML
applet thatdocument
it has
4Embeddedinform
in an
Called
by theinto
browser
to
been
loaded
the
through the
<Applet>
tag.
inform
this
applet
that
ittoshould
Called
by
the
browser
system.
start
its
execution.
inform
this applet that it should
4Four special
methods:
Called by the browser when
stop its execution.
the applet is being reclaimed
Ð Init
and should destroy any
Ð Start
resources that it has allocated
Ð Stop
Ð Destroy
Applets (2)
4Security restrictions:
Ð No access to the file system on the client
Ð No access to serial or parallel ports
Ð And others...
4Full access to GUI
Getting documentation
4Full online documentation to the
Java API
4Documentation always up-to-date
through javadoc : classes hierarchy,
fields, methods,etc...
Writing a Java applet
Creating a new type
ÒExtendsÓ the
Applet class
inherits
4The new type must inheritand
from
theits
java.applet.Applet
class
Set the
Java primitive
convention sooperations
that
with Java.Applet.Applet;
are
package Tictactoesubprograms
is
with the with
t y p e Typ is new compatible
Java.Applet.Applet.Typ
inherited Java API
record
É
end record;
pragma Convention (Java, Typ);
end Tictactoe;
Writing a Java applet
Adding fields (1)
4Creating Record components
Ð Mapped to object fields of the Java class
type Typ is new É with
record
First
: Boolean;
Is_New_Game: Boolean;
NotImage
: Java.Awt.Image.Ref;
CrossImage
: Java.Awt.Image.Ref;
end record;
Writing a Java applet
Adding fields (2)
4Global variables
Ð Mapped to ÒstaticÓ Java fields
package Tictactoe is
É
White
: aliased Position;
Black
: aliased Position;
OK
: constant Integer := 0;
Win : constant Integer := 1;
...
end Tictactoe;
Writing a Java applet
Writing new subprograms (1)
4Creating new primitive subprograms
function Your_Move (Board : access Typ;
M : Square)
Has to be a primitive return Boolean;
operation
of Typ in
(could
Name visible
the
useJVM.
ÒinÓ Used
or Òinwhen
outÓ
parameters)
interfacing to Java
4Specifying a specific external name
pragma Export (Java, Your_Move, ÒyourMoveÓ);
Writing a Java applet
Writing new subprograms (2)
4Creating non-primitive subprograms
Ð Mapped to ÒstaticÓ Java functions
type Position is array (0 .. 8) of Boolean;
function Is_A_Winner (Pos : access Position)
return Boolean;
Writing a Java applet
Overriding inherited subprograms
4Must have the same prototype as in
the Java API
procedure Paint (This : access Typ;
G1 : access Graphics.Typ'Class);
procedure Init (This : access Typ);
Called to initialize the
Special function called
applet
every time the applet
needs
to be redrawn
Writing a Java applet
Implementing an interface (1)
4Reacting to events requires
implementing the relevant Java
interface
Ð The subprograms will be called
automatically by the JVM on each
event (mouse, keyboard):
mousePressed, mouseReleased, etc...
Writing a Java applet
Implementing an interface (2)
4Interfaces are declared by applying
pragma Java_Interface
to
an abstract
used
The typeDiscriminant
must be
type
abstract,for
asconversion
well as
the subprograms
package Java.Awt.Event.MouseListener
is
type Typ (Self : access Object.Typ'Class) is
abstract new Java.Lang.Object.Typ with
Declares the type as
record
a Java interface
É
end record;
pragma Java_Interface ( T y p) ;
end MouseListener;
Writing a Java applet
Implementing an interface (3)
One discriminant
4Interfaces per
areinterface,
implemented
used
for conversions
access discriminants
using
type Typ
(I_ImageObserver : access ImageObserver.Typ'Class;
I_MouseListener : access Mouselistener.Typ'Class)
is new Java.Applet.Applet.Typ (I_ImageObserver)
with record
É
end record;
Writing a Java applet
Implementing an interface (4)
4Interface subprograms must be
overridden
procedure mouseReleased
(This : access Typ;
E : access MouseEvent.Typ'Class);
pragma Convention (Java, MouseReleased);
4pragma Convention currently
needed so that the compiler can
generate the call properly
Writing a Java applet
Interfacing to Java functions (1)
4Create a public static Java function
public class support {
static public String convert (byte s []) {
return new String (s);
}}
4This function will be implemented as
an intrinsic operator (Ò+Ó)
Writing a Java applet
Interfacing to Java functions (2)
4Create an Ada spec for this Java
function
package Support is
function Convert (S : String) return String.Ref;
private
pragma Import (Java, Convert, "convert");
end Support;
pragma Import (Java, Support, "support");
Compiling the Applet
4jvm2ada generates the Ada specs for
the Java API classes
4jgnatmake: recompiles each package
needed by your applet
Ð Creates a set of Java class files
Ð Invokes jgnatbind to generate the
elaboration code
Running the Applet (1)
4Create a HTML document containing
an <applet> Tag
<applet CODEBASE=Ò.Ó
CODE=Òtictactoe$typ.classÓ
WIDTH=200 HEIGHT=200>
Sorry, can't show the applet</applet>
4All classes must be in the same
directory
Running the Applet (2)
4Appletviewer
4Web Browser
Ð Netscape
Ð Internet Explorer
Ð HotJava
Ð etc...
Conclusion
4Most details can be ignored when
not interfacing the Java API
4Multi-threading supported
4Ada library not completely
supported yet, but a good part of it is
available (Text_IO, etcÉ)
GNAT:
Complete Ada Solution
100% Java compatible
Téléchargement