114
Prácticas de Diseño y Aplicaciones de Sistemas Distribuidos (DYA) Joan Vila Carbó José Simó Ten .

Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Embed Size (px)

Citation preview

Page 1: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Prácticas de

Diseño y Aplicaciones de Sistemas Distribuidos

(DYA)

Joan Vila CarbóJosé Simó Ten

.

Page 2: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos
Page 3: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Juan V

PRÁCTICA 1 Introducción a Java y Eclipse 1El entorno de trabajo 1El directorio de trabajo 2Desarrollo de un proyecto elemental: Hola mundo! 4Desarrollo de algunas otras aplicaciones básicas en Java 5Ficheros de apoyo 6

PRÁCTICA 2 El servicio de “echo” con sockets 15Estructura de la aplicación 15Realización de la parte básica de la práctica 17Realización de variantes de la práctica 19Ficheros de apoyo 20

PRÁCTICA 3 El servicio de “echo” en Java-RMI 29Estructura de la aplicación 30Realización del servicio de echo elemental en RMI 31Despliegue y ejecución de aplicacione RMI desde la consola. 34Realización de la aplicación “echo” utilizando movilidad de código 35Ficheros de apoyo 37

PRÁCTICA 4 El servicio de “echo” en CORBA 39Estructura de la aplicación 40Realización de la parte básica de la práctica. 41Utilización del servicio de nombres CORBA 44La plataforma Orbacus 46Ficheros de apoyo 49

PRÁCTICA 5 Difusión y grupos dinámicos: la agencia de robots 51Estructura de la aplicación 52Realización de la parte básica de la práctica: bibliotecas para comunicación 58Realización de los objetos remotos CORBA 59Ficheros de apoyo 62

PRÁCTICA 6 El applet echo 71Estructura de la aplicación 72Realización de la parte básica de la práctica 73Ejecución del applet echo como aplicación web 76

ila Carbó 1

Page 4: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

PRÁCTICA 7 Servlets 81Introducción a servlets 82Descripción de la aplicación 83Realización de la parte básica de la práctica. 85Ampliaciones de la práctica 88Ficheros de apoyo 89

PRÁCTICA 8 Servicios web con SOAP y Eclipse 97Invocación de un servicio web disponible en Internet 98Creación de un Servicio web 100Invocación de servicios web desde programas en Java 101Ficheros de apoyo 102

PRÁCTICA 9 Seguridad 105Applets firmado 105El protocolo SSL y la técnica de tunneling 107

2

Page 5: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

PRÁCTICA 1 Introducción a Java y Eclipse

DYA

sta práctica se dedica, fundamentalmente, a conocer el entorno de trabajo para

desarrollo de aplicaciones en Java en el entorno Eclipse. Este IDE es un proyecto

de software libre y está apoyado por gran nuúmero de empresas con interés en el

lenguaje Java y también en otros lenguajes. Se encuentra disponible para las plataformas

Linux, Windows y Mac OS en http://ww.eclipse.org:

Esta práctica introduce el método de trabajo a seguir en cada práctica y a la programación

básica en Java.

1.1.- El entorno de trabajo

El entorno de trabajo está formado, básicamente, por:

1. El IDE Eclipse es una herramienta de software libre para desarrollo de programas enJava, disponible para plataformas Linux, MacOs X y Windows XP. Disponible en:

E

1

Page 6: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

El directorio de trabajo

http://www.eclipse.org/downloads/Su funcionalidad se puede ampliar con plugins. El programa de prácticas de la asignaturarequiere instalar especificamente los siguientes plugins:- Plugin RMI Genady

- Name: RMI Plugin for Eclipse v2.0 - URL: http//www.genady.net/rmi/v20/install/

- Plugin CORBA ORBstudio

- Descargar de: http//www.orbzone.org- Plugin Visual Editor (VE)

- Parte de la distribución Europa. Descargar con el update manager del repositorioCallisto.

- Plugin Web Tool Platforms (WTP).

- Parte de la distribución Europa. Descargar con el update manager del repositorio WTPupdates.

2. Los recursos disponibles en el PoliformaT de la asignatura: - Enunciados y ficheros de apoyo para la realización de las prácticas.

- Documentación sobre Java, incluyendo el API de programación y el tutorial "The Java Tuto-rial: Object Oriented Programming for the Internet" de K. Walrath y M. Campione.

1.2.- El directorio de trabajoEn primer lugar es necesario tener una idea clara a la estructura de directorios. Aunque

parezca simple, esta es una de las mayores fuentes de problemas en todas las prácticas. Eclipse

requiere utilizar un directorio de trabajo base o workspace referido como $WS. Puede utilizar por

ejemplo:

UNIX -> DIRECTORIO BASE ($WS) : $HOME/workspace WINDOWS -> DIRECTORIO BASE ($WS) : C:\Documents and Settings\USER\workspace

Recuerde que el laboratorio no garantiza preservar el contenido de los directorios de discos locales.

Por tanto, es su responsabilidad almacenar sus programas la unidad W: que proporciona la UPV a

cada estudiante al final de cada práctica.

Para recuperar un proyecto de una sesión de trabajo anterior alamacenado en la unidad W: al direc-

torio de trabajo, deberá realizarlo con la opción Import de Eclipse.

2 Introducción a Java y Eclipse

Page 7: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

El directorio de trabajo

DYA

1.2.1.- Estructura del directorio de trabajo

Cada práctica constituirá un proyecto Java (Java project) de Eclipse. Cada proyecto es un

directorio que tendrá dos subdirectorios src para ubicar el código fuente y bin para el código objeto

(.class).

A su vez, cada proyecto constará de varios paquetes (o packages). Cada uno de estos packages

constituye, a su vez, un subdirectorio de los directorios src y bin.

Así por ejemplo, un proyecto denominado prj-sockets, con dos paquetes denominados client y ser-

ver tendrá la siguiente estructura:

$WS/prj-sockets$WS/prj-sockets/src$WS/prj-sockets/src/client$WS/prj-sockets/src/server$WS/prj-sockets/bin/client$WS/prj-sockets/bin/server

Esta estructura de directorios es la que utilizan la mayoría de los IDE’s para desarrollo de Java,

incluyendo Eclipse y JBuilder.

1.2.2.- Inicializando los contenidos del directorio de trabajo

Algunas prácticas disponen en la web de un fichero comprimido (.zip) con material de

apoyo. Este material está organizado normalmente según la estructura de directorios de un proyecto

arriba indicada. El subdirectorio src contiene ficheros fuente cuya implementación está incompleta.

Los ejercicios a realizar para completar la implementación del fichero fuente se encuentran enun-

ciados como comentarios en el propio fichero.

Cuando necesite utilizar los ficheros de apoyo el método será el siguiente.

1. Descargar el fichero zip con el material de apoyo a un directorio de descargas referido como $DL

(p.e. $DL=$HOME/descargas) y descomprimirlo, creando la estructura de directorios arriba indi-cada.

2. Copiar el fichero desede el directorio de descargas:$DL/prj-hola/src/hola/fichero.java

al correspondiente directorio del workspace:$WS/prj-hola/src/hola/fichero.java

3. Es necesario actualizar la ventana del Package Explorer del IDE Eclipse (Refresh / tecla F5)cada vez que se añade un nuevo paquete o fichero al proyecto de forma externa a Eclipse paraque este se aperciba de los cambios o nuevos ficheros introducidos.

3

Page 8: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Desarrollo de un proyecto elemental: Hola mundo!

4.

1.3.- Desarrollo de un proyecto elemental: Hola mundo!Para desarrollar un proyecto Java previamente creado, según se detalla en el apartado ante-

rior, básicamente han de seguirse los pasos que a continuación se detallan:

1. Abrir el IDE Eclipse y escoger como directorio workspace el directorio $WS/

2. Crear un proyecto Java (por ejemplo prj-hola para la primera práctica) en el IDE Eclipse, espe-cificando que se creen subdirectorios separados para código fuente (src) y código objeto (bin)con la opción: ‘Create separate source and output folders’.

3. Crear en el proyecto los paquetes necesarios para el desarrollo de la práctica. En este caso soloexiste un único paquete denominado hola.

4. Crear un fichero HolaMundo.java, en el paquete en que deba incluirse, que en este caso es elpaquete hola. Opción: New->Class + public static void main

5. Editar y completar la aplicación HolaMundo.java.- Puede ser interesante en este apartado utilizar el menú Help y la opción Dynamic Help para

consultar el API de una determinada clase Java que se desee utilizar, por ejemplo la claseSystem.

6. La compilación de todos los ficheros de que consta un proyecto se realizará automáticamentecada vez que salve el fichero si la opcion Project-> Build automatically se encuentra activada.Los errores vienen indicados a principio de la línea correspondiente del editor. La causa del errory la corrección sugerida se obtienen haciendo click sobre el icono del error.

7. Ejecutar y depurar el programa HolaMundo.java. La forma más sencilla de ejecutar un pro-grama es con el menú Run del IDE Eclipse. El proyecto será recompilado cada vez que ejecuteel programa.- Los programas sencillos y sin argumentos pueden ejecutarse con la opción Run as -> Java

Application.

- Los programas que necesiten argumentos, argumentos de la máquina virtual o modificar pro-piedades de Java precisan crear un perfil de ejecución con la opción Run... que despliega unmenú de ventanas con distintos parámetros de ejecución. Cree un perfil para esta aplicación yguárdelo con el nombre HolaMundo.

- Una opción interesante cuando se depura un programa (no tan simple como este) es la coloca-ción de puntos de ruptura o Breakpoints. Esto se realiza en la barra izquierda de la ventanadel editor de programas.

- Observe que la ejecución de un programa abre una nueva ventana de tipo Console en la parteinferior del IDE Eclipse donde se realiza la E/S.

- Si introduce un error en su programa, verá que el listado de errores aparece en la ventana Pro-blems ubicada en la misma zona que la ventanas Console. Observe también las posibilidades

4 Introducción a Java y Eclipse

Page 9: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Desarrollo de algunas otras aplicaciones básicas en Java

DYA

que ofrecen los controles sobre este tipo de ventanas (abrir, cerrar, fijar, maximizar, lim-piar,...) de la parte inferior del IDE.

8. El código objeto generado se almacena en el directorio $WS/prj-sockets/bin/ pero también puedecrear un fichero tipo JAR (Java Archive) que empaquete el código objeto de un proyecto. Estefichero puede generarse con la opción Export->Java->JAR file aplicada sobre el paquete que sevisualiza la ventana del Package Explorer. Este fichero se ubica el directorio base del works-pace. Puede ejecutarse externamente a Eclipse si al crear el JAR se especifica la clase principal.

1.4.- Desarrollo de algunas otras aplicaciones básicas en JavaUna vez ha desarrollado la aplicación HolaMundo!, se propone completar el paquete hola

con otras aplicaciones básicas en Java. Estas aplicaciones se encuentran a medio resolver como

ficheros de apoyo. En esta caso la metodología a seguir es:

1. Incluir el fichero en el proyecto. Para ello, cópielo (en vez de crearlo) desde el directorio de des-cargas al directorio de trabajo o workspace. Actualizar la ventana del Package Explorer delIDE Eclipse (tecla F5) cada vez que se añade un nuevo paquete o fichero al proyecto y compro-bar que esos paquetes se visualizan y son accesibles desde el editor de programas.

2. Editarlo, y realizar los ejercicios propuestos sobre el propio código fuente: puede requerir con-sultar la ayuda del API con Dynamic Help.

3. Ejecutarlo y depurarlo: Cree un perfil de ejecución con el diálogo Run... para cada ejercicio pro-puesto.

Los ejercicios propuestos son, por este orden:

• Objetos.java: ejercicios sobre clases, herencia, objetos,...

• Relojes.java: ejercicios de utilización de la clase Thread.

• CountFile.java: cuenta los caracteres de un fichero. Ejemplo de trabajo con ficheros.

• CopyFile.java: copia ficheros. Ejemplo de trabajo con ficheros.

• EntradaSalida.java: ejercicios con sentencias de E/S con streams.

• DataIOTest.java: ejercicios de escritura y lectura de datos numéricos de un fichero.

5

Page 10: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

1.5.- Ficheros de apoyo

1.5.1.- Fichero Objetos.javapackage hola;

import java.io.*;

class Punto { public int x = 0; public int y = 0;

public Punto(int x, int y) { this.x = x; this.y = y; }}

class Rectangulo { protected Punto origen; protected int ancho = 0; protected int alto = 0; private static String nombreClase ="Rectangulo";

public Rectangulo(int origenx, int origeny, int ancho, int alto){ origen=new Punto(origenx, origeny); this.ancho=ancho; this.alto=alto; } public Rectangulo(Punto p, int ancho, int alto){ origen= p; this.ancho=ancho; this.alto=alto; } public Rectangulo(int ancho, int alto){ origen= new Punto(0,0); this.ancho=ancho; this.alto=alto; } public Rectangulo(){ origen= new Punto(0,0); this.ancho=0; this.alto=0; } public int ancho(){ return ancho; } public int alto(){return alto; } public int area(){return (ancho*alto); } public void mover(int arriba, int derecha){ origen.x+=arriba; origen.y+=derecha; } public String toString() {

6 Introducción a Java y Eclipse

Page 11: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

return "(Origen: {" + Integer.toString(origen.x) + "," + Integer.toString(origen.y) + "}, Final: {" + Integer.toString(origen.x+ancho) + "," + Integer.toString(origen.y+alto) + "})"; } public static String nombre(){ return nombreClase; } protected void finalize() throws Throwable { origen = null; super.finalize(); }}

//EJERCICIO: Implemente una clase RectanguloColor, basándose en la clase Rectangulo.

//EJERCICIO: con un nuevo atributo color y sobrecargando el método toStringclass RectanguloColor extends Rectangulo {

//EJERCICIO: ... public String toString() {

//EJERCICIO: Sobrecargue este método para que incluya en el String también el color

}}

class CuadradoColor extends RectanguloColor { public CuadradoColor(Punto p, int lado, int color){ super(p,lado,lado,color);}}

public class Objetos{

static Rectangulo R1 = new Rectangulo(1,1,7,8); static Rectangulo R2 = new Rectangulo(new Punto(2,2),7,8); static Rectangulo R3 ; static RectanguloColor RC; static CuadradoColor C;

public static void main(String args[]) throws IOException{ if (args.length < 4){ System.out.println("Uso: Objetos origen-x origen-y ancho alto"); System.exit(1); }

int[] i = new int[4]; int j = 0;

for(j=0; j < i.length; j++) i[j] = Integer.parseInt(args[j]); R3 = new Rectangulo(i[0],i[1],i[2],i[3]);

RC= //EJERCICIO: Cree una instancia de rectángulo color RC

7

Page 12: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

//EJERCICIO: que añada a R3 el atributo de color.

System.out.println("Nombre de la clase: " + Rectangulo.nombre()); System.out.println("Nombre de la clase de R3: " + R3.nombre()); System.out.println("Area de R3: " + R3.area()); System.out.println("R3: " + R3.toString()); System.out.println("RC: " + RC.toString());

//EJERCICIO: Invoque el método mover(10,10) sobre R3

//EJERCICIO: Invoque el método toString sobre R3 y RC

//EJERCICIO: y visualicelos por pantalla el resultado

//PREGUNTA: Se ha "movido" R3? y RC? Debería haberse "movido" RC?

// Explique convenientemente este aspecto.

C= //EJERCICIO: Cree un CuadradoColor con origen en

// el punto: (2,2),alto=5,ancho=25 System.out.println("C: " + C.toString()); System.out.println("Area de C: " + C.area());

}}

1.5.2.- Fichero Relojes.javapackage hola;

import java.text.*;import java.util.*;

class Reloj extends Thread {int cuenta=0;public Reloj(String nombre, int cuenta) { super(nombre); this.cuenta=cuenta; } public void start() { Date h = new Date(); System.out.println(getName() + "-> " + DateFormat.getTimeInstance(3,Locale.FRANCE).format(h) + " Faltan " + cuenta + " seg. para la alarma"); super.start(); }

public void run() { for (int i = 1; i <= cuenta; i++) {

//EJERCICIO: Provoque un retraso de 1000 milisegundos } System.out.println(getName() + "Riiinnnng!!!"); }}

public class Relojes {

8 Introducción a Java y Eclipse

Page 13: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

public static void main(String[] args){

//EJERCICIO: Cree dos instancias de la clase Reloj}}

1.5.3.- Fichero CountFile.javapackage hola;

import java.io.*;

class CountFile { public static void main(String[] args) throws java.io.IOException, java.io.FileNotFoundException { int count = 0; InputStream is; String filename;

if (args.length >= 1) {

// EJERCICIO: Cree una instancia de FileInputStream, llamada is,

// para leer del fichero que se especifica como args[0] filename = args[0]; } else { is = System.in; filename = "Input"; }

while (is./* EJERCICIO: */!= -1)

//EJERCICIO: utilice un metodo de FileInputStream para leer un caracter count++;

System.out.println(filename + " has " + count + " chars."); }

1.5.4.- Fichero CopyFile.javapackage hola;

import java.io.*;

class CopyFile { public static void main(String[] args) throws java.io.IOException, java.io.FileNotFoundException { byte[] buffer = new byte[256]; int count;

if (args.length == 2) {

// EJERCICIO: Cree una instancia de FileInputStream, llamada is,

// para leer del fichero que se especifica como args[0]

9

Page 14: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

// EJERCICIO: Cree una instancia de FileOutputStream, llamada os,

// para escribir en el fichero que se especifica como args[1]

while ((count=is.read(buffer)) != -1) os.write(buffer,0,count); } else { System.out.println("Se necesitan dos argumentos"); }

}}

1.5.5.- Fichero EntradaSalida.javapackage hola;import java.io.*;

public class EntradaSalida{

public static void main(String args[]) throws IOException{ int j; byte[] buffer = new byte[80]; String filename, filename2; float f1 = (float) 3.1416; float f2 = 0;

try { //E/S con InputStream y OutputStream System.out.println("Teclee una cadena"); j = System.in.read(buffer); System.out.print("La cadena: "); System.out.write(buffer,0,j);

//Convertimos cadena de bytes a cadena de caracteres (2 bytes) String tira = new String(buffer,0,j); System.out.println("Otra vez la cadena: " + tira);

//E/S con BufferedReader y PrintWriter //Conveniente con cadenas de caracteres (1 caracter = 2 bytes) BufferedReader stdIn = new BufferedReader( new InputStreamReader(System.in)); PrintWriter stdOut = new PrintWriter(System.out);

//E/S con InputStream y OutputStream System.out.println("Teclee un entero");

//EJERCICIO: Lea un entero por teclado e imprÌmalo en pantalla

//E/S con BufferedReader y PrintWriter //Conveniente con cadenas de caracteres (1 caracter = 2 bytes) System.out.println("Teclee un nombre para un fichero");

//EJERCICIO: Lea de teclado una cadena para el nombre del fichero

// y almacénela en la variable filename

10 Introducción a Java y Eclipse

Page 15: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

//E/S con ficheros y floats en formato numerico

//EJERCICIO: Escriba un float en el fichero filename (en formato binario)

//EJERCICIO: Lea el float que ha escrito en el fichero filename

//EJERCICIO: Escriba el float que ha leido del fichero filename en pantalla

//AYUDA: Mire el cÛdigo de un poco mas abajo...

// Es parecido (pero en formato de texto)

//E/S con ficheros y floats en formato de texto filename2=filename + ".txt"; System.out.println("Fichero: "+filename2);

PrintWriter fout2 = new PrintWriter(new FileOutputStream(filename2));

BufferedReader fin2 = new BufferedReader( new InputStreamReader(new FileInputStream(filename2))); fout2.println(new Float(f1).toString()); fout2.flush(); f2=Float.valueOf(fin2.readLine()).floatValue();

System.out.println("Escrito y leido el float: " +f2+ " del fichero: " +filename2); } catch (IOException e) { System.out.println("Error en E/S"); System.exit(1); }}}

1.5.6.- Fichero DataIOTest.java

/Se trata de escribir en un fichero con formato:

//

// 9.99 12 Java T-shirt

// 9.99 8 Java Mug

// 15.99 13 Duke Juggling Dolls

//

// y luego leerlo y sacarlo por pantalla

// NOTA: los datos numéricos deben escribirse como "números" y

// no como cadenas de caracteres.

// NOTA: los Strings deben escribirse como cadenas de bytes

// no como cadenas de caracteres (1caracter = 2 bytes)package hola;import java.io.*;

public class DataIOTest { public static void main(String[] args) throws IOException {

//E/S con DataInputStream y DataOutputStream //Conveniente con datos numéricos (stream = secuencia de bytes) //Aconsejable para ficheros o sockets pero no para teclado y pantalla

11

Page 16: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

//EJERCICIO: Instancie un objeto de tipo DataOutputStream para escribir

// en el fichero "invoice1.txt" DataOutputStream out =

//EJERCICIO: Instancie un objeto de tipo DataInputStream para leer

// del fichero "invoice1.txt" DataInputStream in =

//Los datos son: double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 }; int[] units = { 12, 8, 13, 29, 50 }; String[] descs = { "Java T-shirt", "Java Mug", "Duke Juggling Dolls", "Java Pin", "Java Key Chain" };

//Un bucle para escribir for (int i = 0; i < prices.length; i ++) { out.writeDouble(prices[i]); out.writeChar('\t'); out.writeInt(units[i]); out.writeChar('\t'); out.writeBytes(descs[i]); out.writeChar('\n'); } out.close();

//Un bucle para leer double price; int unit; String desc; double total = 0.0;

try { while (true) {

//EJERCICIO: leer el primer double del fichero sobre la variable price in.readChar(); // throws out the tab

//EJERCICIO: leer el int siguiente sobre la variable unit in.readChar(); // throws out the tab

//EJERCICIO: leer la cadena siguiente sobre la variable desc System.out.println("You've ordered " + unit + " units of " + desc + " at $" + price); total = total + unit * price; } } catch (EOFException e) { } System.out.println("For a TOTAL of: $" + total); in.close(); while (true){}; }

12 Introducción a Java y Eclipse

Page 17: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

}

13

Page 18: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

14 Introducción a Java y Eclipse

Page 19: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

PRÁCTICA 2 El servicio de “echo” con sockets

DYA

l objetivo de esta práctica es crear y ejecutar una aplicación cliente servidor "echo"

basada en sockets TCP pero estructurándola según el modelo de objetos distribui-

dos.

La comunicación remota se realizará utilizando el método de RPC (Remote Procedure Call)

o invocaciones remotas a procedimientos (métodos de objetos en este caso). Esta primera

práctica de comunicación remota pretende demostrar cómo realizar los stubs y esqueletos

de la RPC manualmente. En las siguientes prácticas ya se generarán de forma automática.

2.1.- Estructura de la aplicación

La aplicación Echo se estructura en tres paquetes: la interfaz, el cliente y el servidor, los

cuales se describen a continuación. Ver figura 1 (pág. 16).

2.1.1.- El paquete interfaz (rmi)

Consta del siguiente fichero:

E

15

Page 20: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Estructura de la aplicación

• EchoInt.java: describe el servicio "echo". Su finalidad es proporcionar a este servicio una inter-

faz de invocación a objeto remoto, ocultando el hecho de que la comunicación se realiza

mediante sockets. Este fichero se encuentra completamente implementado. Visite este código y

observe que lo único sorprendente de este código es la propagación de la siguiente excepción de

RMI:

throws java.rmi.RemoteException: representa cualquier error de comunicación remota.

Cualquier excepción de comunicación con sockets debe ser reconvertido a esta excepción. Esto se

realiza para mantener una uniformidad de Interfaz con la práctica siguiente sobre RMI. Allí se com-

prenderá plenamente.

2.1.2.- El paquete servidor (server)

Consta, básicamente, de los siguientes ficheros:

• EchoObject.java: implementa la interfaz EchoInt y proporciona el servicio de "echo". La

implementación de ste servicio consiste en devolver la cadena que se envía, junto con el URL y

la hora de la máquina servidora al cabo de 3 segundos. Este retraso simula que el servicio tiene

un tiempo de cómputo largo y apreciable. Visite este código.

• EchoServer.java: es el esqueleto de un servidor secuencial que realiza las siguientes operacio-

nes:

- Recibe una conexión a través de un socket

FIGURA 1. Estructura de una RPC

echo:(s: String)

EchoObject.javaEcho.java

echo(s: String)

EchoStub.java EchoServer.java

Código de red

C S

Misma interfazEchoInt.java

Paquete: client Paquete: server

Paquete: rmi

16 El servicio de “echo” con sockets

Page 21: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de la parte básica de la práctica

DYA

- Invoca un objeto de l clase EchoObject.java

- Devuelve la respuesta de la anterior invocación por el socket

Este fichero se encuentra completamente implementado. Visite este código y observe el manejo de

sockets.

Existe también una segunda versión multihilo de EchoServer.java denominada EchoMultiSer-

ver.java que se analizará más adelante.

2.1.3.- El paquete cliente (client)

Consta, básicamente, de los siguientes ficheros:

• Echo.java: es el cliente propiamente dicho. Realiza el siguiente bucle:

- Leer de teclado

- Invocar el stub

- Imprimir el resultado por pantalla.

Visite este código y observe que existen EJERCICIOS.

• EchoObjectStub.java: es el proxy del objeto en el nodo del cliente (stub del cliente). Observe

que implementa la misma interfaz que el objeto: interfaz EchoInt y, adicionalmente, el método

setHostAndPort, para especificar con que host y port se van a realizar las conexiones. Visite

este código y observe que existen EJERCICIOS.

Existe también una segunda versión de este fichero denominada EchoObjectStub4.java que imple-

menta una política diferente de conexión/desconexión con el servidor que se analizará más ade-

lante.

2.2.- Realización de la parte básica de la prácticaPara la realización de la parte básica de la práctica cree un proyecto prj-sockets y siga la

metodología descrita en la práctica 1 para el desarrollo de una aplicación Java.

1. Descargue los ficheros de ayuda al directorio de descargas.

2. Cree un proyecto prj-sockets en el workspace según se indica en la práctica 1 cree también lospaquetes de que consta la aplicación: rmi, client, server.

17

Page 22: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de la parte básica de la práctica

2.2.1.- Versión no distribuida

En primer lugar se desarollará una versión no distribuida de la práctica con “llamada local a

procedimiento”. Se asumirá que la parte cliente y la servidora se encuentran en la misma máquina y

el programa cliente invoca los servicios mediante invocación usual de un método Java. En esta ver-

sión no existen stubs. Ver figura 2 (pág. 18).

Para ello:

3. Incluya en el proyecto los ficheros necesarios para esta parte, copiándolos del directorio de des-cargas al workspace y actualizando la visión del Package explorer. - Paquete rmi: fichero EchoInt.java . El fichero se encuentra completamente terminado.

- Paquete server: fichero EchoObject.java. El fichero se encuentra completamente terminado.

- Paquete client: fichero Echo.java. Incluya en este fichero una invocación local.

4. Escriba el código necesario y ejecute la aplicación.

2.2.2.- Versión distribuida

Posteriormente incluya los stubs necesarios en cada paquete y desarrolle la versión distribuida de la

aplicación:

5. Desarrolle el paquete server:- Copie el fichero EchoServer.java del directorio de descargas al workspace.

- Realice los ejercicios propuestos.

- Ejecute y depure EchoSever.java utilizando el menú Run... y proporcionado los parámetrosde ejecución que sean necesarios.

6. Desarrolle el paquete client:- Copie el fichero EchoObjectStub.java del directorio de descargas al workspace.

- Realice los ejercicios propuestos.

FIGURA 2. Versión no distribuida de la práctica

18 El servicio de “echo” con sockets

Page 23: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de variantes de la práctica

DYA

- Ejecute y depure Echo.java utilizando el menú Run... y proporcionado los parámetros de eje-cución que sean necesarios.

7. Compruebe el correcto funcionamiento del cliente y servidores del servicio de echo conectán-dose con servidores remotos desarrollados por sus compañeros (y viceversa).

2.3.- Realización de variantes de la prácticaEn relación con esta práctica se proponen realizar dos ejercicios más avanzados con varian-

tes del stub del cliente y del esqueleto del servidor. Estas variantes se proponen en los siguientes

puntos.

2.3.1.- Servidor de echo multihilo.

Un servidor de echo multihilo es un servidor que debe ser capaz de atender varias peticiones

concurrentemente. La ejecución solapada de las diferentes peticiones se puede observar creando

varios clientes e iniciando peticiones de servicio desde todos ellos de forma más o menos simultá-

nea. La duración de tres segundos para la ejecución del servicio permitirá observar que las ejecucio-

nes se solapan en el tiempo.

Para la realización de este servicio, deberá realizar un nuevo esqueleto del servidor cuya implemen-

tación parcial se proporciona en el fichero EchoMultiServer.java. que sustituirá al antiguo esque-

leto monohilo del servidor EchoServer.java. El fichero EchoObject.java que implementa el

servicio, será el mismo que en el caso anterior.

2.3.2.- Stub del cliente con desconexión por timeout

En este apartado se propone sustituir el stub del cliente de echo EchoObjectStub. java por

un nuevo stub EschoObjectStub2. java que gestione las conexiones con el servidor con otra polí-

tica. El stub original cabría una conexión al principio de cada petición y la cerraba al final de la

misma. Para evitar la sobrecarga de abrir y cerrar conexiones cuando se producen peticiones muy

frecuentes se propone realizar un nuevo stub del cliente con la siguiente política de gestión de

conexiones:

- Cuando termina una petición el stub del cliente programa la desconexión con el servi-dor para la cabo de 5 segundos. - Si el cliente realiza una petición y existe una conexión establecida, se envían los datosal servidor por la conexión existente, sino, se abre una nueva conexión y se envían los datosal servidor.

19

Page 24: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

- Si durante los cinco segundos siguientes a una invocación no llegan nuevas peticiones,se cierra automáticamente la conexión.

La figura figura 3 (pág. 20) (a) muestra un cronograma de conexiones y desconexiones que indica

cuándo debe hacerse una conexión, cuándo debe programarse una desconexión, cuando debe desco-

nectarse y cuándo debe cancelarse una desconexión programada. Asimismo, la figura (b) ilustra

cómo debe evitarse que la desconexión ocurra estando una petición en marcha

Se recomienda realizar una clase Timeout en base a las clases Timer y TimerTask:

public class Timer extends ObjectA facility for threads to schedule tasks for future execution in a background thread. Tasks may be scheduled for one-time execution, or for repeated execution at regular intervals.

public abstract class TimerTask extends Object implements RunnableA task that can be scheduled for one-time or repeated execution by a Timer

2.4.- Ficheros de apoyo

2.4.1.- Fichero rmi/EchoInt.javapackage rmi;public interface EchoInt extends java.rmi.Remote { public String echo(String input)throws java.rmi.RemoteException;}

FIGURA 3. gestión de la desconexión con timeout en stubs

20 El servicio de “echo” con sockets

Page 25: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

2.4.2.- Fichero server/EchoObject.javapackage server;

import java.net.*;import java.io.*;import java.text.*;import java.util.*;

public class EchoObject implements EchoInt { String myURL="localhost";

public EchoObject(){ try { myURL=InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException e) { myURL="localhost"; } }

public String echo(String input) throws java.rmi.RemoteException { Date h = new Date(); String fecha = DateFormat.getTimeInstance(3,Locale.FRANCE).format(h);

String ret = myURL + ":" + fecha + "> " + input; System.out.println("Procesando: '" + input + "'"); try { Thread.sleep(3000); ret = ret + " (retrasada 3 segundos)"; } catch (InterruptedException e) {} System.out.println("Procesamiento de '"+ input +"' terminado."); return ret; }}

2.4.3.- Fichero server/EchoServer.javapackage server;

import java.net.*;import java.io.*;

public class EchoServer { private static EchoObject eo = new EchoObject(); private static String myURL="localhost";

private static ServerSocket serverSocket = null; private static Socket clientSocket = null; private static BufferedReader is = null; private static PrintWriter os = null; private static String inputline = new String();

public static void main(String[] args) { try { myURL=InetAddress.getLocalHost().getHostName();

21

Page 26: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

} catch (UnknownHostException e) { System.out.println("Unknown Host :" + e.toString()); System.exit(1); }

try { serverSocket = new ServerSocket(7); } catch (IOException e) { System.out.println(myURL + ": could not listen on port: 7, " + e.toString()); System.exit(1); } System.out.println(myURL + ": EchoServer listening on port: 7");

try { boolean listening = true; while(listening){ clientSocket = serverSocket.accept(); is = new BufferedReader( new InputStreamReader( clientSocket.getInputStream())); os = new PrintWriter(clientSocket.getOutputStream()); while ((inputline = is.readLine()) != null) { os.println(eo.echo(inputline)); os.flush(); }

os.close(); is.close(); clientSocket.close(); }

serverSocket.close(); } catch (IOException e) { System.err.println("Error sending/receiving" + e.getMessage()); e.printStackTrace(); } }}

2.4.4.- Fichero server/EchoMultiServer.javapackage server;

import java.net.*;import java.io.*;

public class EchoMultiServer { private static ServerSocket serverSocket = null;

public static void main(String[] args) {

try { serverSocket = new ServerSocket(7); } catch (IOException e) { System.out.println("EchoMultiServer: could not listen on port: 7, " + e.toString());

22 El servicio de “echo” con sockets

Page 27: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

System.exit(1); } System.out.println("EchoMultiServer listening on port: 7");

boolean listening = true; while (listening) {

//EJERCICIO: aceptar una nueva conexión

//EJERCICIO: y crear un Thread para que la gestione }

try { serverSocket.close(); } catch (IOException e) { System.err.println("Could not close server socket." + e.getMessage()); } }}

//----------------------------------------------------------------------------// class EchoMultiServerThread//----------------------------------------------------------------------------

class EchoMultiServerThread extends Thread { private static EchoObject eo = new EchoObject(); private Socket clientSocket = null; private String myURL = "localhost"; private BufferedReader is = null; private PrintWriter os = null; private String inputline = new String();

EchoMultiServerThread(Socket socket) { super("EchoMultiServerThread"); clientSocket = socket; try {

is = new BufferedReader(new InputStreamReader( //EJERCICIO ... ));

os = new PrintWriter( //EJERCICIO ... ); } catch (IOException e) { System.err.println("Error sending/receiving" + e.getMessage()); e.printStackTrace(); } try { myURL=InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException e) { System.out.println("Unknown Host :" + e.toString()); System.exit(1); } }

public void run() { try { while ((inputline = is.readLine()) != null) {

//EJERCICIO: Invocar el objeto

//EJERCICIO: y devolver la respuesta por el socket

23

Page 28: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

}

os.close(); is.close(); clientSocket.close(); } catch (IOException e) { System.err.println("Error sending/receiving" + e.getMessage()); e.printStackTrace(); } }}

2.4.5.- Fichero client/Echo.javapackage client;

import java.io.*;import java.net.*;

public class Echo {private static EchoObjectStub ss;

public static void main(String[] args) {

if (args.length<2) { System.out.println("Usage: Echo <host> <port#>"); System.exit(1); }

ss = //EJERCICIO: crear una instancia del stub ss.setHostAndPort(args[0],Integer.parseInt(args[1]));

BufferedReader stdIn = new BufferedReader( new InputStreamReader(System.in)); PrintWriter stdOut = new PrintWriter(System.out); String input,output; try {

//EJERCICIO: el bucle infinito:

//EJERCICIO: Leer de teclado

//EJERCICIO: Invocar el stub

//EJERCICIO: Imprimir por pantalla } catch (UnknownHostException e) { System.err.println("Don't know about host: "+ args[0]);

} catch (IOException e) { System.err.println("I/O failed for connection to: "+args[0]); } }}

2.4.6.- Fichero client/EchoObjectStub.javapackage client;

import java.net.*;import java.io.*;

24 El servicio de “echo” con sockets

Page 29: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

class EchoObjectStub implements EchoInt{

private Socket echoSocket = null; private PrintWriter os = null; private BufferedReader is = null; private String host = "localhost"; private int port=7; private String output = "Error"; private boolean connected = false;

public void setHostAndPort(String host, int port) { this.host= host; this.port =port; }

public String echo(String input)throws java.rmi.RemoteException { connect(); if (echoSocket != null && os != null && is != null) { try { os.println(input); os.flush(); output= is.readLine(); } catch (IOException e) { System.err.println("I/O failed in reading/writing socket"); throw new java.rmi.RemoteException("I/O failed in reading/writing socket"); } } disconnect(); return output; }

private synchronized void connect() throws java.rmi.RemoteException {

//EJERCICIO: Implemente el método connect }

private synchronized void disconnect(){

//EJERCICIO: Implemente el método disconnect }}

2.4.7.- Fichero client/EchoStub2.javapackage client;

import java.net.*;import java.io.*;

class EchoObjectStub implements EchoInt, Runnable {

private Socket echoSocket = null; private PrintWriter os = null; private BufferedReader is = null; private String host = "localhost";

25

Page 30: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

private int port=7; private String output = "Error"; private boolean connected = false;

private Thread reloj = new Thread(this, "reloj"); private int timeout = 50; private boolean firstTime = true;

public void setHostAndPort(String host, int port) { this.host= host; this.port =port; }

public String echo(String input)throws java.rmi.RemoteException { connect(); if (echoSocket != null && os != null && is != null) { try { os.println(input); os.flush(); output= is.readLine(); } catch (IOException e) { System.err.println("I/O failed in reading/writing socket"); throw new java.rmi.RemoteException("I/O failed in reading/writing socket"); } } programDisconnection(); return output; }

private synchronized void connect() throws java.rmi.RemoteException {

//EJERCICIO: lo mismo que en EchoObjectStub }

private synchronized void disconnect(){

//EJERCICIO: lo mismo que en EchoObjectStub }

private synchronized void programDisconnection(){

//EJERCICIO: programar un timeout para la cabo de 5 segundos

}

class Timeout {

Timer timer; EchoObjectStub stub; int seconds;

public Timeout (int seconds, EchoObjectStub stub) { this.seconds = seconds; this.stub = stub; }

public void start() {

//EJERCICIO

26 El servicio de “echo” con sockets

Page 31: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

}

public void cancel() {

//EJERCICIO }

class TimeoutTask extends TimerTask {

//EJERCICIO }}

}

27

Page 32: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

28 El servicio de “echo” con sockets

Page 33: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

PRÁCTICA 3 El servicio de “echo” en Java-RMI

DYA

l objetivo de esta práctica es crear y ejecutar una aplicación cliente servidor “echo”

basada en java-RMI. La práctica tiene dos partes:

La primera parte implementa un servidor sencillo basado en un objeto java-RMI con un

único método “echo”.

La segunda parte utiliza las facilidades de movilidad de código en Java-RMI. Se trata de

implementar también el servicio de “echo”, pero esta vez el servidor es una máquina de

cómputo genérica, denominada “ComputeEngine”, que puede ejecutar cualquier algoritmo

cuyo código se le proporcione a través de la red. En este caso, el algoritmo será el algoritmo

del servicio de “echo”.

La metodología de desarrollo de aplicaciones RMI propuesta en esta práctica está basada en

el plugin de RMI para Eclipse de http//www.genady.net. Esta metodología se encuentra bien

detallada en las Flash demos que se encuentran en la web y que pueden accederse también a

través del menú desplegable del plugin RMI.

E

29

Page 34: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Estructura de la aplicación

3.1.- Estructura de la aplicación

La aplicación Echo se estructura en tres paquetes: la interfaz, el cliente y el servidor, los cuales se

describen a continuación. Ver figura 1 (pág. 30).

3.1.1.- El paquete interfaz (rmi)

Consta del siguiente fichero:

• EchoInt.java: describe el servicio “echo”. Este fichero debe ser prácticamente igual a la interfaz

especificada en la práctica anterior, excepto que el interfaz es en esta práctica es subclase de

java.rmi.Remote.

public interface EchoIntRMI extends java.rmi.Remote

3.1.2.- El paquete servidor (server)

Consta, básicamente, de dos ficheros:

• EchoObject.java: implementa la interfaz EchoInt y proporciona el servicio de “echo” en local

(a clientes locales, no a clientes remotos). La implementación es idéntica a la práctica anterior y

consiste en devolver la cadena que se envía, junto con el URL y la hora de la máquina servidora

al cabo de 3 segundos. Este retraso simula que el servicio tiene un tiempo de cómputo largo y

apreciable.

FIGURA 1. Estructura de una RPC

30 El servicio de “echo” en Java-RMI

Page 35: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización del servicio de echo elemental en RMI

DYA

• EchoObjectRMI.java: es el verdadero objeto RMI (extends UnicastRemoteObject). También

implementa la interfaz EchoInt e implementa el servicio de “echo” en remoto (para clientes

remotos). Su implementación se basa en crear una instancia del objeto EchoObject y delegar en

el la implementación del método echo. La funcionalidad adicional que aporta esta clase es la de

registrar el servicio en el servidor de nombres y proporcionarle la capacidad de ser invocado

remotamente mediante el código genético que aporta la clase UnicastRemoteObject.

El objeto servidor lo componen el código objeto correspondiente a estos ficheros junto a los skele-

tons generados automáticamente por RMI.

3.1.3.- El paquete cliente (client)

Lo constituye el siguiente fichero:

• EchoRMI.java: es el cliente RMI. Se encarga de obtener una referencia RMI al objeto servidor

a partir del servicio de nombres. Una vez obtenida esta referencia, realiza el bucle:

- Leer de teclado

- Invocar el objeto (a través de la referencia al objeto)

- Imprimir el resultado por pantalla.

3.2.- Realización del servicio de echo elemental en RMIPara la realización de la parte básica de la práctica cree un proyecto prj-rmi y siga la meto-

dología descrita en la práctica 1.

3.2.1.- Creación del proyecto

1. Descargue los ficheros de ayuda al directorio de descargas ($WS/descargas) si los hubiera.

2. Cree un proyecto prj-rmi en el workspace según se indica en la práctica 1 cree también lospaquetes de que consta la aplicación: rmi, client, server.

3.2.2.- Generación de la interfaz RMI

El desarrollo de la interfaz RMI, contenida en el paquete rmi, consta de los siguientes pasos:

3. Cree una interfaz EchoInt. La opción más sencilla es utilizar File->New->Other->Java->RMI -> Remote Interface. También se puede hacer con File->New->New Interface especificando:

- Name: EchoInt

31

Page 36: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización del servicio de echo elemental en RMI

- Extended interfaces: java.rmi.Remote4. Complete la definición de la interfaz con la especificación del método echo.

3.2.3.- Generación del servidor RMI

El desarrollo del servidor RMI, contenido en el paquete server, consta de los siguientes

pasos:

5. Cree una clase EchoObjectRMI. con File->New Class especificando: - Name: EchoObjectRMI - Superclass: java.rmi.UnicastRemoteObject - Extended interfaces: rmi.EchoInt - public static void main - Constructors from superclass

6. Copie el fichero EchoObject.java del directorio de descargas al directorio server del proyectoen el workspace y actualice el Package explorer para visualizarlo.

7. Complete la implementación del servidor con la implementación de los métodos echo y main.- El método echo delega en el correspondiente método de la clase EchoObject.

- El método main básicamente debe realizar una instancia del EchoObjectRMI e inscribirla enel Servicio de Nombres de RMI

3.2.4.- Generación de stubs

La ejecución de aplicaciones RMI requiere la generación automática de stubs y skeletons,

para ello:

8. Habilite la generación de stubs RMI para el servidor del proyecto. Para ello en el menú contex-tual del proyecto seleccione:- RMI->Enable Stubs Generation

Esto generará los stubs cada vez que sea necesario (si el proyecto tiene seleccionada la opciónProject->Build automatically) pero el package explorer normalmente no los muestra.

9. Para mostrar los stubs en el Package explorer deberá habilitar la siguiente opción en el menúcontextual del proyecto:- Properties -> -keep

En caso de no disponer del plugin RMI, la generación de stubs y skeletons puede realizarsedesde una consola MS-DOS estableciendo la variable de entorno CLASSPATH y ejecutando elcompilador de RMI, especificando como parámetros el servidor de echo: > rmic server/EchoObjectRMI.java

3.2.5.- Generación del cliente RMI

El desarrollo del cliente RMI, contenido en el paquete client, consta de los siguientes pasos:

32 El servicio de “echo” en Java-RMI

Page 37: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización del servicio de echo elemental en RMI

DYA

10. Copie el fichero EchoRMI.java del directorio de descargas al directorio client del proyecto en elworkspace y actualice el Package explorer para visualizarlo.

11. Realice los ejercicios propuestos. - Sólo tiene que realizar la invocación al servidor de echo.

- Observe la necesidad de un gestor de seguridad en el cliente.

3.2.6.- Compilación y ejecución de aplicaciones RMI en Eclipse

El desarrollo de aplicaciones RMI en Eclipse se ve facilitado por el plugin de http://

www.genady.net. Para ejecutar una aplicación RMI, básicamente debe seguir los siguientes pasos:

1. Arranque el servicio de nombres RMI rmiregistry utilizando la opción Start Local Registry(port 1099) del menú del plugin de RMI:En caso de no disponer del plugin RMI, este servicio también puede arrancarse desde una con-sola MS-DOS estableciendo la variable de entorno CLASSPATH y ejecutando:> start rmiregistry

En Unix:> rmiregistry&

2. Ejecute el servidor EchoObjectRMI creando un perfil de ejecución con el menú Run as -> RMIApplication y fijando las siguientes propiedades de la máquina virtual (menú RMI VM Pro-perties):- java.rmi.server.codebase: permite especificar un URL para el código rmi. De esta forma, la

máquina virtual puede conocer la ubicación de las clases y sus correspondientes stubs o ske-letons. Fíjela en el directorio bin de la aplicación (file:${workspace_loc:/prj-rmi/bin}). Estaopción se especifica con Compute from classpath.

- La ejecución de aplicaciones desde consola (caso de no disponer del plugin RMI) debe espe-cificar correctamente las propiedades de la máquina virtual:

> java server/EchoObjectRMI -Djava.rmi.server.codebase= ... -Djava.security.policy=...

3. Compruebe que el servicio echo ha sido registrado correctamente en el rmiregistry utilizando elRMI Registry Inspector.

4. Ejecute el cliente EchoRMI creando un perfil de ejecución con el menú Run as -> RMI Appli-cation y especificando:- Argumentos de ejecución (menú (x) Arguments): host del servidor.

- Propiedades de la máquina virtual (menú RMI VM Properties). Puesto que el cliente utilizaun gestor de seguridad es necesario especificar una política:

- java.security.policy: permite especificar el URL para un fichero con la política de seguridadnecesaria para ejecutar aplicaciones RMI. Existen aquí dos opciones: o bien crear un fichero

33

Page 38: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Despliegue y ejecución de aplicacione RMI desde la consola.

automáticamente desde las opciones disponibles (Create...) o bien especificar un fichero conel siguiente contenido.

grant { permission java.net.SocketPermission "*:1024-65535", "connect,accept,resolve"; };

5. Realice también pruebas de invocación de clientes a servidores remotos utilizando el servidor deecho de otros compañeros de prácticas.

3.3.- Despliegue y ejecución de aplicacione RMI desde la consola.La ejecución de la aplicación RMI fuera del entorno Eclipse consta de dos pasos fundamen-

tales el despliegue de la aplicación como ficheros jar y la ejecución, propiamante dicha, del servidor

y del cliente.

3.3.1.- Despliegue de la aplicación

Deben generarse los siguientes ficheros jar:

1. rmi_remote.jar: contiene los interfaces y los stubs de RMI. Debe estar accesible por el clienteen tiempo de ejecución. En el caso de la práctica “Echo” contiene:rmi/EchoInt.javaserver/EchoObjectRMI_Stub.java

2. rmi_server.jar: contiene la implementación del servidor. En el caso de la práctica “Echo” con-tiene:rmi/EchoInt.javaserver/*

1.

2. rmi_client.jar: contiene la implementación del cliente. En el caso de la práctica “Echo” con-tiene:rmi/EchoInt.javaclient/*

3.3.2.- Ejecución del servidor RMI

La ejecución del servidor consta de los siguientes pasos:

1. Ejecutar el servicio de nombres rmiregistry en la máquina que se ejecute el servidor.2. Crear un fichero de política de segurida denominado, por ejemplo, “security.policy” con el

siguiente contenido:grant { permission java.security.AllPermission; }

34 El servicio de “echo” en Java-RMI

Page 39: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de la aplicación “echo” utilizando movilidad de código

DYA

3. Dejar el fichero “rmi_remote.jar”con la implementación del servidor en una localización accesi-ble tanto por parte del servidor como del cliente (hhtp:, ftp:, ó file: ). Por ejemplo:file:/users/dya/echo/rmi_remote.jar

4. La máquina java que ejecute al servidor debe tener establecidos las siguientes propiedades: - -Djava.security.policy=“el fichero del paso 2” - -Djava.rmi.server.codebase=Localización del fichero “rmi_remote.jar” - -classpath rmi_server.jar

En el caso de la práctica de Echo - java -Djava.security.policy=security.policy - -Djava.rmi.server.codebase=file:/users/dya/echo/rmi_remote.jar - -classpath rmi_server.jar server.EchoObjectRMI

3.3.3.- Ejecución del cliente RMI

Para ejecutar el cliente RMI, el fichero “rmi_remote.jar” con los stubs y el fichero de polí-

tica de seguridad deben estar accesibles en la máquina del cliente. La ejecución se realiza mediante

la siguiente orden:

java -Djava.security.policy=security.policy -Djava.rmi.server.codebase=file:/users/dya/echo/rmi_remote.jar -classpath rmi_client.jar client.EchoRMI localhost

3.4.- Realización de la aplicación “echo” utilizando movilidad de código

Visite el Tutorial de Java (disponible en la web de la asignatura) y seleccione el capítulo de RMI.

En este capítulo se desarrolla una aplicación donde existe un servidor de computo genérico Compu-

teEngine, que ejecuta un código (subclase de Task) que el cliente le puede especificar como pará-

metro por valor en una invocación RMI (movilidad de código). La Task que se desarrolla en el

tutorial es las Task Pi que contiene un algoritmo para calcular el número pi. Ver figura 2 (pág. 36).

Este ejemplo se encuentra disponible como tutorial en el plugin RMI.

Esta segunda parte de la práctica consiste en compilar y ejecutar el ejemplo del tutorial y,

posteriormente, modificarlo para sustituir el algoritmo de calcular el numero pi por el algoritmo de

realizar el servicio “echo”. De esta manera el servidor ComputeEngine ejecutará una Task con el

servicio de “echo”.

Se requiere también modificar la interfaz del Compute del ComputeEngine para adaptarla a la

siguiente especificación:

35

Page 40: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de la aplicación “echo” utilizando movilidad de código

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

public interface Compute extends Remote {

//loadTask: Cargar una nueva task en el ComputeEngine. No ejecutarla void loadTask(Task t) throws RemoteException;

//executeTask: Ejecutar una task previamente cargada con loadTask

//la task admite como argumentos de entrada los proporcionados en arg y

//el resultado de la Task es devuelto como resultado de executeTask Object executeTask(Object arg) throws RemoteException; }

Esta segunda parte consta de los siguientes pasos:

1. Crear los proyectos de esta aplicación con: File->New->Other->Java->RMI -> Tutorials yseleccionando Sun’s RMI Tutorial.

2. Ejecutar la aplicación anterior. Para ello, siga los pasos del apartado 3.2.6.-3. Modificar la aplicación anterior para ajustarse a la nueva especificación de la interfaz Compute.

Para ello:- Modifique las interfaces Compute y Task.

- Modifique el servidor de ComputeEngine para implementar la nueva interfaz Compute.

- Realice una Task que implemente el algoritmo de echo, aprovechando el objeto EchoOb-ject.java.

- Realice una nueva versión del cliente de echo de la primera parte de la práctica para que invo-que la nueva máquina de cómputo genérica.

4. Ejecute la nueva versión del servidor de cómputo genérico.

FIGURA 2. La aplicación ComputeEngine

36 El servicio de “echo” en Java-RMI

Page 41: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

3.5.- Ficheros de apoyo

3.5.1.- Fichero server/EchoObjectRMI.java

3.5.2.- package server;

import java.rmi.RemoteException;import java.rmi.registry.LocateRegistry;import java.rmi.registry.Registry;

import java.rmi.server.UnicastRemoteObject;

import rmi.EchoInt;

public class EchoObjectRMI extends UnicastRemoteObject implements EchoInt {

private static final long serialVersionUID = 1L;

protected EchoObjectRMI() throws RemoteException { super(); // TODO Auto-generated constructor stub}

private static EchoObject eo = new EchoObject();

public String echo(String input) throws RemoteException {// TODO Auto-generated method stub

return eo.echo(input);}

public static void main(String[] args) {

// TODO Auto-generated method stub

try {

Registry registry = LocateRegistry.getRegistry();

registry.rebind("echo", new EchoObjectRMI());

} catch (RemoteException e) {

System.err.println("Something wrong happended on the remote end");

e.printStackTrace();

System.exit(-1); // can't just return, rmi threads may not exit

}

System.out.println("The echo server is ready"); }}

3.5.3.- Fichero server/EchoObject.java

El mismo que para la práctica de sockets.

37

Page 42: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

3.5.4.- Fichero client/EchoObject.javapackage client;

import java.io.*;import java.rmi.Naming;import java.rmi.RMISecurityManager;import rmi.EchoInt;

public class EchoRMI {

public static void main(String[] args) {

// TODO Auto-generated method stub if (args.length<1){ System.out.println("Uso echo <host>");System.exit(1); }

if(System.getSecurityManager()== null) System.setSecurityManager(new RMISecurityManager());

BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); PrintWriter stdOut = new PrintWriter(System.out);

String input,output; try{ EchoInt obj = (EchoInt) Naming.lookup("//" + args[0] + "/echo"); stdOut.print("> "); stdOut.flush(); while ( (input = stdIn.readLine())!=null){

//EJERCICIO: invocar el objeto RMI stdOut.println(output); stdOut.print("> "); stdOut.flush(); } }catch(Exception e){ System.out.println("Error en el cliente de echo RMI : " + e.getMessage()); } }}

38 El servicio de “echo” en Java-RMI

Page 43: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

PRÁCTICA 4 El servicio de “echo” en CORBA

DYA

la arquitectura CORBA permite la realización de aplicaciones distribuidas hetero-

géneas siguiendo el modelo de programación orientada a objetos. El objetivo de

esta práctica es crear y ejecutar la aplicación cliente/servidor “echo”, siguiendo la

metodología de objetos distribuidos de CORBA.‘

La práctica consta dos partes. En la primera parte la referencia IOR a un servidor se rea-

liza a partir de un fichero creado por el servidor. En la segunda parte, la referencia IOR al

servidor se obtiene a partir de un servicio de nombres de CORBA donde el servidor lo ha

registrado previamente.

La metodología de desarrollo de aplicaciones CORBA propuesta en esta práctica está

basada en el plugin de ORB Studio para Eclipse de http//www.orbzone.org. También se uti-

lizará en la segunda parte el servicio de nombres de la plataforma Orbacus, cuyas bibliote-

cas y documentación se pueden encontrar en la página de prácticas de la web de la

asignatura. Esta práctica desarrolla los contenidos del capítulo 2 (Getting Started) del

manual de Orbacus. Ambos plugins son de la compañía IONA.

L

39

Page 44: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Estructura de la aplicación

4.1.- Estructura de la aplicaciónEsta aplicación consta de una interfaz IDL y tres paquetes: cliente, el servidor, y corba, los

cuales se describen a continuación. La estructura de la aplicación se representa en la figura 1 (pág.

40).

4.1.1.- La interfaz IDL

Las interfaces de servicios se especifican en CORBA utilizando el lenguaje IDL. La interfaz

se encuentra definida en el siguiente fichero:

• Echo.idl: interfaz en IDL del servicio “echo”.

4.1.2.- El paquete corba

Este paquete agrupa los stubs y el soporte necesario para implementar servicio “echo” en

CORBA. Se generan automáticamente al procesar la interfaz IDL (Echo.idl). Estos ficheros no han

de ser modificados, y sólo deben regenerarse en caso de modificar la interfaz IDL. Son los siguien-

tes ficheros:

- Echo.java y EchoOperations.java: son la interfaz java derivada de la interfaz IDL.

- EchoPOA.java: integra el stub del servidor.

- _EchoStub.java: integra el stub del cliente (proxy)

- EchoHelper.java: proporciona funcionalidad extra, fundamentalmente el método narrow paraconvertir referencias CORBA a su correspondientes tipos.

FIGURA 1. Estructura de una aplicación CORBA

40 El servicio de “echo” en CORBA

Page 45: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de la parte básica de la práctica.

DYA

- EchoHolder.java: proporciona objetos y métodos para los argumentos out e inout de CORBAque no se ajustan fácilmente a la semántica de Java

4.1.3.- El paquete servidor (server)

Consta de lo siguientes ficheros:

• Server_AOM.java: tiene la estructura típica de un servidor CORBA. Realiza la inicialización

del objeto CORBA y se encarga de publicar su IOR, bien sea en un fichero o en el servicio de

nombres CORBA.

• EchoSeverImpl.java: es el objeto que implementa todos los métodos definidos en el interfaz

IDL. En este caso, dicha implementación se basa en crear una instancia del objeto EchoObject

utilizado en las dos prácticas anteriores, y delegar en disco objeto la implementación del método

EchoObject.echo definido en el interfaz.

• EchoObject.java: Implementa el método echo tal como establece el interfaz IDL. Es el mismo

fichero de implementación que en prácticas anteriores.

4.1.4.- El paquete cliente (client)

Consta de lo siguientes ficheros:

• EchoClient.java: tiene la estructura típica de un cliente CORBA. Se encarga de realizar la ini-

cialización del objeto CORBA, obtener un IOR al objeto servidor e invocarlo.

Los argumentos para invocar el servicio “echo” los proporcionará el usuario por teclado y lavisualización de la respuesta del servicio se realizará por consola. Este código también seincluirá en este fichero.

La obtención de un IOR al objeto servidor se realizará de dos formas diferentes. En la partebásica de la práctica (apartado 4.2.-) el cliente obtiene el IOR a partir de un fichero creado por elservidor. En el apartado 4.3.- el cliente obtiene el IOR del servicio de nombres de CORBA,donde el servidor lo ha registrado previamente.

4.2.- Realización de la parte básica de la práctica.La parte básica de la práctica no utiliza el Naming Service o el Trading Service de CORBA

para la obtención de IORs a servicios sino que, en su lugar, se utiliza simplemente un fichero.

41

Page 46: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de la parte básica de la práctica.

4.2.1.- Publicación del IOR

El método que utiliza el servidor ara publicar el IOR (referencia a si mismo) del servicio que oferta

es escribirlo en forma de string en un fichero llamado server.ior. El cliente obtendrá el IOR del ser-

vidor a partir de dicho fichero. Puesto que el cliente normalmente se encuentra en una máquina dis-

tinta a la del servidor, habrá que hacer alcanzable este fichero al cliente por algún medio:

publicándolo en una web, enviándolo un correo-e, enviándolo en un disquete, compartiendo un

directorio que contenga el fichero,...).

Tenga en cuenta que cada vez que el proceso servidor muere y vuelve a ser ejecutado el IOR gene-

rado es diferente (aunque se trate del mismo servicio). Ello requerirá que el cliente vuelva a renovar

el IOR cuando sospeche que haya podido ocurrir esta situación.

La realización de la parte básica de la práctica se describe en los siguientes apartados.

4.2.2.- Creación del proyecto

Básicamente se siguen los pasos de práctica anteriores:

1. Compruebe que el plugin ORB Studio utiliza como plataforma CORBA el soporte Java IDL quese proporciona con el JDK. Para ello seleccione Eclipse->Preferences->ORB Studio->IDLCompiler y seleccione JavaIDL(JDK)

2. Cree un proyecto prj-corba en el workspace (W:\dya) según se indica en la práctica 1. Puesto quese elige como plataforma CORBA el JavaIDL del JDK no es necesario especificar bibliotecasextra. Cuando se utilice Orbacus habrá que añadirlas.

4.2.3.- Generación y procesamiento de la interfaz IDL

3. Genere un nuevo fichero IDL en su proyecto con el wizard de ORB studio. Para ello, seleccioneel proyecto prj-corba y en el menú contextual elija New->Other->CORBA Wizard->SimpleIDL y dele nombre al fichero Echo.idl.

4. Abra el fichero Echo.idl generado automáticamente con el editor de IDL integrado en Eclipse.Edite este fichero y realice la especificación del servicio de echo (ver ficheros de apoyo). Espe-cifique como module (se mapea a package en Java) corba. El editor de IDL comprueba la sin-taxis automáticamente.

5. Genere stubs y esqueletos compilando el fichero IDL. El compilador también se integra enEclipse al instalar el plugin. Para compilar, seleccione el fichero Echo.idl y en el menú contex-tual elija ORB menu->Compile. Observe el paquete con el soporte CORBA generado por elcompilador.

42 El servicio de “echo” en CORBA

Page 47: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de la parte básica de la práctica.

DYA

4.2.4.- Generación del servidor CORBA

La generación de un servidor CORBA que implemente la interfaz IDL descrita consta de

los siguientes pasos:

6. Genere el servidor CORBA. Esta es la principal característica del plugin y la más útil. Se sopor-tan todos los tipos de adaptadores de objetos mencionados en la especificación de OMGCORBA. El código generado es directamente ejecutable y no contiene errores, aunque si partespor completar. En esta práctica se utilizará el tipo de servidor más popular basado en ActiveObject Map (AOM). Seleccione el proyecto prj-corba y en el menú contextual elija New->Other->CORBA Wizard->Server->Active Object Map. Establezca:- Project: prj-corba

- IDL filename: Echo.idl

- Interface: corba.Echo

- Package: server

- Server class name: EchoServerImpl

En la siguiente página del wizard, seleccione sólo la opción:- Create server class

Esto genera dos ficheros en el paquete server del proyecto:- El servant: EchoServerImpl.java

- El server: Server_AOM.java

Además Eclipse reporta un error en la clase del servant. Este error se debe a que la clase del ser-vant no incluye ninguna operación que corresponda a los métodos definidos en IDL. No se pre-ocupe, pues vamos a generarlos.

7. Genere automáticamente en el servant los métodos declarados en la interfaz IDL. Para ello:- Pinche en la marca X en rojo que aparece en la parte derecha del editor de Java y seleccione

que se abra un Assist menu.

- Seleccione en el Assist menu Add unimplemented methods.

- Implemente la lógica de negocio del servidor, es decir complete los métodos del servantcorrespondientes a la interfaz IDL. Básicamente consiste en crear una instancia del objetoEchoObject (que es el mismo que en las dos prácticas anteriores) y delegar en el la imple-mentación del método echo.

8. Cree un perfil de ejecución para el servidor CORBA con Run...

4.2.5.- Generación del cliente CORBA

La generación de un cliente para el servidor CORBA anterior consta de los siguientes

pasos:

43

Page 48: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Utilización del servicio de nombres CORBA

9. Seleccione el proyecto prj-corba y en el menú contextual elija la opción New->Other->CORBA Wizard->Client->Simple implementation. Establezca:- Project: prj-corba

- IDL filename: Echo.idl

- Interface: corba.Echo

- Package: client

- Server class name: EchoClientImpl

10. Implemente el código del cliente. El código generado en el paso anterior tiene un método mainen el que encontrará comentada una línea que ilustra como invocar el servidor.test.getORBInterface().operation1(“A message in a bottle”);

La implementación del cliente básicamente consisten en: leer una cadena de caracteres porteclado, realizar la invocación CORBA del servicio echo y visualizar la respuesta del por con-sola. El código es completamente similar al del servidor RMI excepto la invocación RMI quedebe sustituirse por la invocación CORBA.

11. Cree un perfil de ejecución para el cliente CORBA con Run...

4.3.- Utilización del servicio de nombres CORBALa realización de esta parte de la práctica consiste en utilizar el Name Service de CORBA,

en lugar del fichero Echo.ref, como forma de publicar el IOR. Esto significa realizar pequeños cam-

bios en el cliente y servidor desarrollados con anterioridad.

4.3.1.- Modificaciones en el servidor

Observe el código generado automáticamente para el servidor CORBA y observará que se

encuentra comentado el código para la utilización del servidor de nombres:

org.omg.CORBA.Object ncobj = orb.resolve_initial_references("NameService");NamingContextExt nc = NamingContextExtHelper.narrow(ncobj);nc.bind(nc.to_name("EchoObject"), obj);

Descomente estas líneas.

Además puede ser interesante establecer el host y port en el que se encuentra el servicio de nom-

bres. Para ello añada en el lugar adecuado las siguientes líneas:

props.put("org.omg.CORBA.ORBInitialHost", "localhost");props.put("org.omg.CORBA.ORBInitialPort", "1050");

44 El servicio de “echo” en CORBA

Page 49: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Utilización del servicio de nombres CORBA

DYA

4.3.2.- Modificaciones en el cliente

Comente las líneas necesarias para deshabilitar la obtención del IOR del fichero server.ior, y

en su lugar añada las líneas:

ncobj = orb.resolve_initial_references("NameService");NamingContextExt nc = NamingContextExtHelper.narrow(ncobj);org.omg.CORBA.Object obj = nc.resolve_str("EchoObject");target = corba.EchoServiceHelper.narrow(obj);

4.3.3.- Ejecución del servicio de nombres de JavaIDL(SDK)

En JavaIDL (SDK) se encuentran disponibles dos servicios de nombres:

• El Servicio de Nombres Persistente: proporciona persistencia a los contextos de nombres. Se

puede invocar de dos formas:

Desde una consola:

$ orbd -1050 &

Desde Eclipse, creando un perfil de ejecución con Run... y la siguiente configuración:

- Name: SDK CORBA Name Service

- Main class: com.sun.corba.se.impl.naming.pcosnaming.NameServer

- Application parameters: -ORBInitialPort 1050

• El Servicio de Nombres Transitorio: si existe una interrupción en el servicio, al rearrancar no

conserva los contextos. Es el más antiguo y sólo se proporciona por compatibilidad hacia atrás.

Se puede invocar de dos formas:

Desde una consola:

$ tnameserv -1050 &

Desde Eclipse, creando un perfil de ejecución con Run... y la siguiente configuración:

- Name: SDK CORBA Transient Name Service

- Main class: com.sun.corba.se.impl.naming.cosnaming.TransientNameServer

- Application parameters: -ORBInitialPort 1050

Se recomienda utilizar el Servicio de Nombres Persistente. Además existe una utilidad servertool

que permite interrogar y visualizar los contenidos del servidor orbd. Se puede invocar de dos for-

mas:

Desde una consola:

45

Page 50: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

La plataforma Orbacus

$ servertool -1050 &

Desde Eclipse, creando un perfil de ejecución con Run... y la siguiente configuración:

- Name: SDK CORBA Name Service Console

- Main class: com.sun.corba.se.impl.activation.ServerTool

- Application parameters: -ORBInitialPort 1050

Arránquela y utilice la orden list o help en el prompt “>” de esta herramienta.

Una vez arrancado el servicio de nombres ya puede ejecutar el servidor y el cliente CORBA.

4.4.- La plataforma OrbacusUna plataforma CORBA alternativa que puede utilizarse para la realización de la práctica es

Orbacus 4.0.3, disponible para Java y C++ sobre Linux y Windows. El software de Orbacus 4.0.3 se

encuentra en la web de la asignatura. y consta, básicamente, de los siguientes elementos:

• Orbacus-4.0.3/JOB-4_0_3.zip: código fuente

• Orbacus-4.0.3/JOB-4_0_3_jars.zip: bibliotecas

• Orbacus-4.0.3/JOB-4_0_3_pdf.zip: documentación

• Orbacus-4.0.3/linux/JOB-4_0_3-bin-linux.zip: ejecutables para linux

• Orbacus-4.0.3/win32/JOB-4_0_3-bin-win32.zip: ejecutables para windows

4.4.1.- Instalación

Para la instalación de este entorno precisa descargar los ficheros JOB-4_0_3_jars.zip y JOB-4_0_3-

bin-win32.zip (o JOB-4_0_3-bin-linux.zip). La documentación no es necesario descargarla, puesto

que se puede consultar también en la web de la asignatura.

1. Descargue los ficheros JOB-4_0_3_jars.zip y JOB-4_0_3-bin-win32.zip (o JOB-4_0_3-bin-linux.zip) al directorio de descargas y descomprímalos.

2. Cree un directorio $WS/JOB-4.0.3 en el workspace con los siguientes subdirectorios:- $WS/JOB-4.0.3/lib: copie a este subdirectorio los ficheros OB.jar, OBNaming.jar, OBU-

tils.jar extraídos del fichero JOB-4_0_3_jars.zip del directorio de descargas.

46 El servicio de “echo” en CORBA

Page 51: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

La plataforma Orbacus

DYA

- $WS/JOB-4.0.3/bin: copie a este subdirectorio el ejecutable jidl (e idlcpp) extraídos delfichero JOB-4_0_3-bin-linux.zip del directorio de descargas.

3. En las propiedades del proyecto incluya los ficheros OB.jar, OBNaming.jar, OBUtils.jar deldirectorio $WS/JOB-4.0.3\lib como bibliotecas del proyecto (pestaña Libraries, opción Addexternal JARs...).

4. El código de cliente y servidor debe modificarse si desea utilizarse esta plataforma CORBA sus-tituyendo las líneas:props.setProperty("org.omg.CORBA.ORBClass", "com.sun.corba.se.internal.POA.POAORB");props.setProperty("org.omg.CORBA.ORBSingletonClass", "com.sun.corba.se.internal.corba.ORBSingleton");

por:props.put("org.omg.CORBA.ORBClass", "com.ooc.CORBA.ORB"); props.put("org.omg.CORBA.ORBSingletonClass", "com.ooc.CORBA.ORBSingleton");

4.4.2.- Compilador de IDL

En el directorio $WS/JOB-4.0.3/bin puede encontrar el ejecutable jidl que se invoca de la

siguiente forma:

$ jidl Echo.idl

Nota: jidl -i Echo.idl genera también el fichero EchoImpl.java con la plantilla para la implementa-

ción de los métodos de una interfaz.

Observe el directorio y los ficheros que genera el compilador al procesar una interfaz IDL.

4.4.3.- El servicio de nombres

El soporte para el servicio de nombres CORBA en Orbacus se encuentra en la biblioteca

OBNaming,jar previamente incluida en el proyecto. Puede invocarse creando un perfil de ejecución

(menú Run...) con la siguiente configuración:

- Name: Orbacus Name Service

- Main class: com.ooc.CosNaming.Server

- Application parameters: -OAPort 1111

Puede ejecutar también Name Service Console de Orbacus que permite observar mediante una

interfaz gráfica los IOR registrados en el Name Service. Para ello, cree un perfil de ejecución (menú

Run...) con la siguiente configuración:

- Name: Orbacus Name Service Console

47

Page 52: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

La plataforma Orbacus

- Main class: com.ooc.CosNamingConsole.Main

- VM parameters: -Dooc.orb.service.NameService=corbaloc::localhost:1111/NameService

Cuando utilice un servicio de nombres que no se encuentre en la máquina local deberá cambiar ade-

cuadamente la propiedad -Dooc.orb.service.NameService para que refleje el URL de la máquina

donde se encuentra.

4.4.4.- Selección de un servicio de nombres

La selección de un servicio de nombres en una determinada plataforma CORBA puede rea-

lizarse de formas diferentes:

• Utilizando el JavaIDL(SDK): estableciendo la propiedad org.omg.CORBA.NameService,

o bien estableciendo las propiedades org.omg.CORBA.ORBInitialHost y

org.omg.CORBA.ORBInitialPort. Puede hacerse de varios modos:

- Como parámetro de ejecución (en el servidor):

- ORBInitRef NameService=corbaloc::<host>:<port>/NameService

- ORBInitialPort <port> - ORBInitialPort <host>

- Como parámetro de ejecución del máquina virtual VM (en el cliente):

- Dorg.omg.CORBA.NameService=corbaloc::<host>:<port>/NameService

- Mediante el URL corbaloc en el código:

props.put("org.omg.CORBA.NameService", "corbaloc::<host>:<port>/NameService");

props.put("org.omg.CORBA.ORBInitialHost", "<host>"); props.put("org.omg.CORBA.ORBInitialPort", "<port>");

• Utilizando Orbacus: estableciendo la propiedad ooc.orb.service.NameService. Puede

hacerse de varios modos:

- Como parámetro de ejecución:

- OAPort <port> - Como parámetro de ejecución del máquina virtual VM

- Dooc.orb.service.NameService=corbaloc::<host>:<port>/NameService

- Mediante el URL corbaloc en el código:

props.put("ooc.orb.service.NameService", "corbaloc::<host>:<port>/NameService");

48 El servicio de “echo” en CORBA

Page 53: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

Mas información sobre el servicio de nombre de Orbacus puede obtenerse consultando los capítulos

9 y 10 del manual de Orbacus, disponible en la web de la asignatura.

4.5.- Ficheros de apoyo

4.5.1.- Fichero Echo.idl

module corba { interface Echo { // Methods

string echoService(in string input); }; };

4.5.2.- Fichero server/EchoObject.java

El mismo que para la práctica de sockets y RMI.

49

Page 54: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

50 El servicio de “echo” en CORBA

Page 55: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

PRÁCTICA 5 Difusión y grupos dinámicos: la agencia de robots

DYA

l objetivo de esta práctica es doble: por una parte, iniciar construir la base principal

del proyecto “Agencia de Robots” que constituye el trabajo final de esta asignatura

y, por otra, conocer la interfaz Java de la primitiva de comunicación de grupos lla-

mada difusión (multicast). Adicionalmente, la práctica también introduce la capacidad para

serializar objetos existente en Java, la cual permitirá enviar objetos Java a través de

conexiones TCP o datagramas UDP.

La aplicación distribuida conocida como la “Agencia de Robots” que se muestra en

la figura 1 (pág. 52)., consiste en un conjunto de robots resolviendo un problema en el que

necesitan coordinarse, como por ejemplo, la persecución entre robots, un partido de fútbol,

etc. Muchas de estas aplicaciones se basan en la utilización de una cámara cenital que

obtiene periódicamente una instantánea del escenario con la posición de todos los robots.

Esta instantánea es difundida a los robots para que estos puedan coordinarse más fácilmente

que basándose exclusivamente en su propia percepción. Además existente otro tipo de com-

ponente denominado consola, que también escucha las difusiones de la cámara y permite

monitorizar el funcionamiento del sistema. Los componentes robot, cámara y consola se

implementarán como objetos remotos. Los objetos robot y consola podrán instanciarse tan-

tas veces como se quiera en diferentes nodos del sistema. De la cámara sólo existirá una

única instancia.

E

51

Page 56: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Estructura de la aplicación

Los robots formarán un grupo dinámico que funciona por subscripción. El objeto “cámara” actuará

no solo como cámara sino como gestor (centralizado) de dicho grupo, dando de alta a aquellos

robots que soliciten su adhesión al grupo y dando de baja a aquellos que deseen abandonarlo o bien

fallen. Sólo los robots subscritos al grupo tendrán acceso al canal de difusión del grupo y podrán,

por tanto, escuchar las difusiones de las instantáneas de la cámara.

La comunicación remota en esta práctica toma dos formas:

• Difusiones de la cámara. Contienen un objeto Java serializado con la instantánea de la cámara.

• Comunicación punto a punto basada en invocaciones CORBA.

Se podrá ampliar el trabajo final para tolerar fallos de la cámara o realizar una versión descentrali-

zada de la misma.

5.1.- Estructura de la aplicaciónEsta aplicación se encuentra estructurada en 6 paquetes, tal como se indica en figura 2 (pág.

53).,. Cada paquete, a su vez, constituye un proyecto diferente. Los tres paquetes fundamentales

corresponden a los tres objetos remotos (robot, cámara y consola) y son completamente indepen-

dientes entre si. Los proyectos/paquetes correspondientes a estos objetos son:

FIGURA 1. La agencia de robots

52 Difusión y grupos dinámicos: la agencia

Page 57: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Estructura de la aplicación

DYA

- prj-robot / package robot: objeto CORBA que simula el comportamiento de los robots. Losrobots se inscriben como componentes del grupo en el gestor del grupo (cámara) y a partir deese momento empiezan a recibir difusiones con instantáneas.

- prj-camara / package camara: objeto CORBA que simula la cámara. Actúa también comogestor del grupo y realiza las difusiones. Puesto que la cámara es simulada y no puede obte-ner las posiciones de los robots mediante un objetivo fotográfico, recurrirá a interrogar a cadarobot para

- Implementado / package consola: objeto CORBA que proporciona una interfaz de usuario.Se proporciona implementado. No se utiliza en este práctica.

Los otros paquetes actúan a modo de bibliotecas utilizadas por los tres primeros y son:

- prj-difusión / package comm: soporte para difusión de objetos serializados. También propor-ciona un package prueba que permite comprobar el correcto funcionamiento. Es el objetivofundamental de esta práctica.

- prj-corba / package corba: soporte CORBA (proxies y stubs) generados automáticamente apartir del procesamiento de la interfaz IDL de la aplicación. La interfaz IDL ya se propor-ciona implementada.

- Implementado / package khepera: biblioteca que simula el funcionamiento de los motores ysensores de infrarrojos del robot conocido como Khepera. No se utiliza en este práctica.

El código objeto de cada proyecto se empaquetará como un archivo JAR (Java ARchive). Cuando

un proyecto A utilice o dependa de otro proyecto B, esta dependencia debe especificarse al crear el

nuevo proyecto B. Esto puede hacerse de dos formas diferentes:

• Si solo se dispone del fichero JAR del proyecto A: incluir el JAR como biblioteca al crear B.

FIGURA 2. Estructura de la aplicación

53

Page 58: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Estructura de la aplicación

• Si se dispone de los fuentes del proyecto A: especificar la dependencia del proyecto A al crear B.

Tiene la ventaja de que si se modifica A, no es necesario regenerar el fichero JAR.

5.1.1.- El proyecto prj-corba

Este proyecto consta de un único paquete: corba. Inicialmente solo contiene el fichero

siguiente:

• robot.idl: definición de las interfaces en el lenguaje IDL-CORBA de los servicios que propor-

cionan la cámara y los robots y de las estructuras necesarias para que se comuniquen entre ellos.

Este fichero se encuentra totalmente implementado (ver ficheros de apoyo).

Observando este fichero se puede observar que, fundamentalmente declara el tipo de datos Instan-

taneaD y dos interfaces: Robot y Cámara.

Estructura de datos InstantaneaDEs la información que la Cámara difunde en las instantáneas y que recolecta información

sobre el estado global del sistema, es decir, con la información de estado del conjunto de robots que

se han suscrito. Esta estructura de datos se declara en IDL como sequence<EstadoRobotD> que en

Java se mapea a un array donde cada elemento es una estructura de tipo EstadoRobotD:

InstantaneaD ---> EstadoRobotD[ ]

La estructura con la información de estado de un Robot es un registro que contiene la siguiente

información:

- string nombre: El nombre del robot.

- unsigned long id: Identificador único del robot.

- string IORrob: IOR (referencia) al robot en forma de string.

Posteriormente se ampliará esta estructura de datos en el trabajo final incluyendo información adi-

cional, como su posición, su objetivo, etc.

Es probable que, por conveniencia de programación, prefiera manejar la estructura de datos instan-

taneaD como un objeto de clase LinkedList de Java en vez de un array, que es lo que produce el

mapeo automático de IDL. Esta conveniencia se basa en que la clase LinkedList ofrece métodos

muy adecuados para la manipulación de colecciones de objetos. Necesitará pues realizar conversio-

54 Difusión y grupos dinámicos: la agencia

Page 59: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Estructura de la aplicación

DYA

nes entre arrays y LinkedList. Para ello, observe que la clase LinkedList dispone de un método

toArray para convertirla en una estructura de datos tipo array.

Procesando el fichero robot.idl con compilador de IDL se generará el resto de ficheros (stubs

CORBA) necesarios para la comunicación CORBA entre objetos remotos. Estos ficheros consti-

tuye el paquete corba.

La interfaz CámaraEn esta interfaz, la Cámara ofrece a otros objetos CORBA únicamente el siguiente servicio:

- Suscribir el robot al grupo: devuelve una estructura de datos SuscripcionD con el identifica-dor único del robot y el canal de difusión.

Este interfaz se ampliará, posteriormente, en el trabajo final para que ofrezca otros servicios, como

dar de baja un robot del grupo, obtener la lista de suscriptores, etc.

Una funcionalidad adicional de la cámara como gestor del grupo es detectar fallos de caída de los

robots. Ante esta situación, el robot que ha fallado se dará de baja de la lista de suscripción. La

estrategia para la detección de fallos de robots consiste en realizar invocaciones periódicas a todos

los robots de la lista de suscripción con el fin de obtener una respuesta y saber así que están vivos.

La interfaz RobotEn esta interfaz, un Robot ofrece a otros objetos CORBA únicamente el siguiente servicio:

- ObtenerEstado: proporciona (a la cámara) la información del estado del Robot.

Este interfaz se ampliará, posteriormente, en el trabajo final para que ofrezca otros servicios.

5.1.2.- El proyecto prj-difusion

Constituye el núcleo central de esta práctica. Contiene dos paquetes: comm y prueba

El paquete commConsta de los siguientes ficheros:

• Difusion.java: ofrece un objeto y métodos para enviar y recibir objetos Java serializados utili-

zando sockets multicast. En este caso se utilizarán para enviar/recibir la estructura de datos Java

a la cual se mapea la definición IDL de InstantaneaD. El fichero se encuentra parcialmente

55

Page 60: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Estructura de la aplicación

implementado y requiere completar los métodos receiveObject(), sendObject() así como el cons-

tructor.

El paquete pruebaEs un paquete cuya única finalidad es poder probar por separado (de forma independiente a

los paquetes Cámara y Robot) el correcto funcionamiento del paquete comm. Solo consta de un

fichero:

• Prueba.java: permite probar y depurar el paquete comm. Básicamente contiene dos threads: uno

que realiza la difusión y otro que la recibe e imprime su contenido. Se encuentra completamente

implementado.

5.1.3.- El proyecto prj-camara

Consta únicamente del paquete Camara con los siguientes ficheros:

• CamaraIntServerImpl.java: contiene el código de aplicación del servidor Cámara. Consta de un

objeto que implementa los métodos de la interfaz IDL de la Cámara. Contiene una clase anidada

(CamaraDifusion) con un thread encargado de enviar periódicamente un objeto InstantaneaD

con el estado global del sistema por un canal de difusión.

• Server_AOM.java: contiene el código CORBA del servidor Cámara. Es el objeto encargado de

convertir la Cámara en un objeto CORBA y registrarlo en el servicio de nombres.

Ambos ficheros se encuentran parcialmente implementados y contienen EJERCICIOS.

La figura figura 3 (pág. 57) muestra el pseudocódigo del código de aplicación del servidor Cámara.,

5.1.4.- El proyecto prj-robot

Este proyecto consta únicamente del paquete Robot con los siguientes ficheros:

• RobotSeguidorIntServerImpl.java: contiene el código de aplicación del servidor Robot. Consta

de un objeto que implementa los métodos de la interfaz IDL del Robot. Contiene una clase ani-

dada (RobotDifusion) con un thread encargado de obtener el canal de difusión y leer periódica-

mente un objeto InstantaneaD difundido por la Cámara. La funcionalidad del Robot en esta

56 Difusión y grupos dinámicos: la agencia

Page 61: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Estructura de la aplicación

DYA

versión preliminar del objeto consiste en recibir el objeto InstantaneaD, deserializarlo e impri-

mir el nombre de todos los robots que se relacionan en InstantaneaD.

• Server_AOM.java: contiene el código CORBA del servidor Robot. Es el objeto encargado de

convertir la cámara en un objeto CORBA, y de obtener una IOR a la Cámara.

Ambos ficheros se encuentran parcialmente implementados y contienen EJERCICIOS.

La figura figura 4 (pág. 57) muestra el pseudocódigo del código de aplicación del servidor Cámara.,

FIGURA 3. Pseudocódigo de la Cámara

FIGURA 4. Pseudocódigo del Robot

57

Page 62: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de la parte básica de la práctica: bibliotecas para comunicación

5.2.- Realización de la parte básica de la práctica: bibliotecas paracomunicación

Esta práctica sirve de esqueleto para el trabajo final. Se encuentra ya resuelto uno de los

aspectos mas importantes: la estructuración en clases y ficheros. Pero a diferencia de otras prácti-

cas, el código propuesto para implementar como ejercicio es mucho mayor. Se pone resolverlo en

varios pasos:

• Implementar el proyecto prj-corba (paquete corba) con la interfaz IDL y crear los stubs

CORBA requeridos para la comunicación remota y las clases java derivadas de la definición

IDL (mappings).

• Implementar el proyecto prj-difusión (paquete comm) para la difusión y probarlo.

• Implementar el proyecto prj-camara (paquete camara) con la versión preliminar del objeto

remoto Camara.

• Implementar el proyecto prj-robot (paquete Robot) con la versión preliminar del objeto remoto

Robot.

Se considerará como parte básica de la práctica la realización de los dos primeros paquetes, corres-

pondientes a las bibliotecas de comunicación por difusión y comunicación CORBA.

Comience por descargar el archivo comprimido con los ficheros de apoyo de la práctica al directo-

rio de descargas y después proceda a la realización de la misma, proyecto a proyecto. Al crear los

proyectos, deberá tener en cuenta que algunos de ellos dependen de otros.

5.2.1.- Realización del proyecto prj-corba

El desarrollo de este proyecto tiene como objetivo crear una biblioteca con el soporte

CORBA creado a partir de la interfaz IDL definida. Requiere los siguientes pasos:

1. Crear el proyecto prj-corba con las opciones habituales. - Si va a utilizar la plataforma CORBA Orbacus, deberá incluir los ficheros OB.jar, OBNa-

ming.jar, OBUtils.jar como bibliotecas al crear el proyecto (pestaña Libraries, opción Addexternal JARs...).

2. Añadir el fichero robot.idl al proyecto, copiándolo desde el directorio de descargas.3. Procesar la interfaz IDL tal como se indicaba en la práctica de introducción a CORBA.

58 Difusión y grupos dinámicos: la agencia

Page 63: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de los objetos remotos CORBA

DYA

4. Crear un fichero JAR con el código objeto generado por el proyecto prj-corba de forma idénticaa como se realizaba en el proyecto anterior.

5.2.2.- Realización del proyecto prj-difusión

El desarrollo de este proyecto tiene como objetivo crear una biblioteca para difusión de

objetos Java y requiere los siguientes pasos:

1. Crear el proyecto prj-difusion con las opciones habituales. Debe especificar la dependencia delproyecto prj-corba o especificar el jar creado a partir de este proyecto como bibioteca.

2. Crear los paquetes comm y prueba3. Añadir los ficheros de apoyo de este proyecto desde el directorio de descargas y actualizar el

Package explorer. 4. Realizar los ejercicios del paquete comm.

- Los constructores.

- El método Object Difusion.receiveObject(): utilice las clases ByteArrayInputStream y Objec-tInputStream.

- El método void Difusion.sendObject(Object object): utilice las clases ByteArrayOutputS-tream y ObjectOutputStream.

5. Crear un fichero JAR con el código objeto generado por el proyecto prj-difusion. Este ficheropuede generarse con la opción Export aplicada sobre el paquete que se visualiza la ventana delPackage Explorer y se ubica el directorio base del workspace.

6. Comprobar el correcto funcionamiento del paquete comm creando un perfil de ejecución para laclase Prueba del paquete prueba:- Un thread difunde un objeto Java (con dos strings: “Hola 1!” y “Hola 2!”), y otro thread escu-

cha la difusión de dicho objeto y visualiza el contenido del objeto difundido.

5.3.- Realización de los objetos remotos CORBAEn esta segunda parte de la práctica se creará un grupo dinámico de Robots con un gestor,

que será la Camara. Los Robots se suscribirán en la Camara y, partir de es momento, comenzarán a

recibir las difusiones que ésta realice. El protocolo de suscripción se realizará utilizando invocacio-

nes CORBA.

5.3.1.- Realización del proyecto prj-camara

El desarrollo de este paquete sigue la metodología para desarrollo de las aplicaciones

CORBA descrita en una práctica de introducción a CORBA. De una manera detallada, los pasos

para la realización de estos paquetes son los siguientes:

59

Page 64: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de los objetos remotos CORBA

1. Cree el proyecto prj-camara con las opciones habituales. En la creación de este proyecto debeespecificar la dependencia de los proyectos prj-difusion y prj-corba (o incluir los jar generadoscomo bibliotecas).

2. Añada al proyecto el ficheros robot.idl, copiándolo desde el directorio de descargas.3. Genere el servidor CORBA. Seleccione el proyecto prj-camara y en el menú contextual elija

New->Other->CORBA Wizard->Server->Active Object Map. Establezca:- Project: prj-camara

- IDL filename: robot.idl

- Interface: corba.CamaraInt

- Package: camara

- Server class name: CamaraIntServerImpl

En la siguiente página del wizard, seleccione sólo la opción:- Create server class

Esto genera dos ficheros en el paquete server del proyecto:- El servant: CamaraIntServerImpl.java

- El server: Server_AOM.java

4. Sobreescriba el servant CamaraIntServerImpl.java con el correspondiente fichero de apoyo,copiándolo desde el directorio de descargas.

5. Realice los ejercicios del servant CamaraIntServerImpl.java. Este objeto implementa la interfazIDL de la cámara. Los aspectos por resolver son: - La implementación de algunos métodos de la interfaz IDL.

- Una clase anidada (CamaraDifusion) que implementa un thread encargado de enviar periódi-camente una InstantáneaD del estado global del sistema por un canal de difusión.

El canal de difusión se especificará como una dirección IP y un port que la Camara recibirácomo argumentos de ejecución. Si no se especifican, tomará unos por defecto.

6. Edite y observe el contenido del fichero Server_AOM.modif del directorio de descargas. Con-tiene modificaciones que debe introducir en el fichero Server_AOM.java. Realícelas en el lugaradecuado.

7. Cree un fichero JAR con el código objeto generado por el proyecto prj-camara de forma idén-tica a como se realizaba en el proyecto anterior.

8. Cree un perfil de ejecución (menú Run...) para la Camara especificando:- Main class: seleccione camara.Server_AOM

- Application parameters: especifique ip port (ip y port del canal de difusión).

60 Difusión y grupos dinámicos: la agencia

Page 65: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de los objetos remotos CORBA

DYA

5.3.2.- Realización del proyecto prj-robot

El desarrollo de este paquete sigue la metodología para desarrollo de las aplicaciones

CORBA descrita en una práctica de introducción a CORBA. De una manera detallada, los pasos

para la realización de estos paquetes son los siguientes:

1. Cree el proyecto prj-robot con las opciones habituales. En la creación de este proyecto debeespecificar la dependencia de los proyectos prj-difusion y prj-corba.

2. Añada al proyecto el fichero robot.idl, copiándolo desde el directorio de descargas.3. Genere el servidor CORBA. Seleccione el proyecto prj-robot y en el menú contextual elija New-

>Other->CORBA Wizard->Server->Active Object Map. Establezca:- Project: prj-robot

- IDL filename: robot.idl

- Interface: corba.RobotSeguidorInt

- Package: robot

- Server class name: RobotSeguidorIntServerImpl

En la siguiente página del wizard, seleccione sólo la opción:- Create server class

Esto genera dos ficheros en el paquete server del proyecto:- El servant: RobotSeguidorServerImpl.java

- El server: Server_AOM.java

4. Sobreescriba el servant RobotSeguidorIntServerImpl.java con el correspondiente fichero deapoyo, copiándolo desde el directorio de descargas.

5. Realice los ejercicios del servant RobotSeguidorIntServerImpl.java. Este objeto implementa lainterfaz IDL de la cámara. Los aspectos por resolver son: - La implementación de algunos métodos de la interfaz IDL

- Una clase anidada (CamaraDifusion) que implementa un thread encargado de recibir periódi-camente la InstantáneaD del estado global del sistema por un canal de difusión.

- El canal de difusión se averiguará a partir de los datos devueltos por la suscripción.

6. Edite y observe el contenido del fichero Server_AOM.modif del directorio de descargas. Con-tiene modificaciones que debe introducir en el fichero Server_AOM.java. Realícelas en el lugaradecuado.

7. Cree un fichero JAR con el código objeto generado por el proyecto prj-robot de forma idéntica acomo se realizaba en el proyecto anterior.

8. Cree un perfil de ejecución (menú Run...) para el Robot especificando:- Main class: seleccione robot.Server_AOM

- Application parameters: especifique un nombre para el robot

61

Page 66: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

5.3.3.- Ejecución de la aplicación

La ejecución de la aplicación requiere ejecutar, en primer lugar, el servicio de nombres

CORBA, después la Cámara y, finalmente, varios Robot.

Para ejecutar el servicio de nombres CORBA, consulte la práctica de introducción a CORBA.

Deberá ejecutar los Robots utilizando como gestor del grupo una Cámara ubicada en una máquina

remota. En este caso, el Robot deberá especificar:

- Application parameters: -ORBInitialPort port -ORBInitialHost host

5.4.- Ficheros de apoyo

5.4.1.- Proyecto prj-difusion

Fichero comm/Difusion.java

package comm;import java.io.*;import java.util.*;import java.net.*;import corba.Instantanea.*;public class Difusion{ MulticastSocket socket; IPYPortD ipyport; public InetAddress group;//------------------------------------------------------------------------------ public Difusion(IPYPortD ipyport){ this.ipyport = ipyport;

//EJERCICIO:

//Crear el socket multicast

//EJERCICIO:

//Obtener la direccion del grupo

//EJERCICIO:

//Unirse al grupo }//------------------------------------------------------------------------------ public Object receiveObject(){ Object object = null; ObjectInputStream ois = null; byte[] buffer; DatagramPacket packet; ByteArrayInputStream bis;

//EJERCICIO: recibir el paquete y deserializarlo return object;

62 Difusión y grupos dinámicos: la agencia

Page 67: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

}//------------------------------------------------------------------------------ public void sendObject(Object object){ ByteArrayOutputStream bos; ObjectOutputStream oos = null; byte[] buffer; DatagramPacket packet;

//EJERCICIO: serializar el paquete y difundirlo }}

Fichero prueba/Prueba.java

package prueba;

import java.util.LinkedList;import comm.*;import corba.Camara.IPYPortD;import corba.Instantanea.*;

//------------------------------------------------------------------------------// La clase Prueba//------------------------------------------------------------------------------public class Prueba { IPYPortD ipyport;

//------------------------------------------------------------------------------ public Prueba(){ ipyport = new IPYPortD("228.1.1.1",1110); new CamaraDifusion(); new RobotDifusion(); }

//------------------------------------------------------------------------------ public static void main(String args[]) { Prueba prueba = new Prueba(); }

//------------------------------------------------------------------------------// La clase anidada CamaraDifusion (el servidor)//------------------------------------------------------------------------------ class CamaraDifusion extends Thread{ Difusion difusion; InstantaneaD instantanea; LinkedList listaEstados = new LinkedList(); EstadoRobotD st1 = new EstadoRobotD(); EstadoRobotD st2 = new EstadoRobotD();

//------------------------------------------------------------------------------ public CamaraDifusion(){ difusion = new Difusion(ipyport); st1.nombre = "Hola 1!"; st2.nombre = "Hola 2!"; listaEstados.add(st1); listaEstados.add(st2); this.start();

63

Page 68: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

}

//------------------------------------------------------------------------------ public void run(){

for(int i=1; i<6; i++) { instantanea = new InstantaneaD((EstadoRobotD[]) listaEstados.toArray(new EstadoRo-botD[0])); difusion.sendObject(instantanea); try{ Thread.sleep(400); }catch(InterruptedException e){ e.printStackTrace(); } } } }//------------------------------------------------------------------------------// La clase anidada RobotDifusion (el cliente)//------------------------------------------------------------------------------ class RobotDifusion extends Thread{ Difusion difusion; InstantaneaD instantanea; EstadoRobotD st = new EstadoRobotD();

//------------------------------------------------------------------------------ public RobotDifusion(){ difusion = new Difusion(ipyport); this.start(); }

//------------------------------------------------------------------------------ public void run(){

while(true){ instantanea = (InstantaneaD) difusion.receiveObject(); System.out.println("-Escuchada difusion-"); for(int i=0; i<instantanea.estadorobs.length; i++){ st = instantanea.estadorobs[i]; System.out.println("Contenido " + i + ": " + st.nombre); } try{ Thread.sleep(400); }catch(InterruptedException e){ e.printStackTrace(); } } } }}

5.4.2.- Fichero robot.idlmodule corba{

64 Difusión y grupos dinámicos: la agencia

Page 69: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

module instantanea{

struct EstadoRobotD { string nombre; unsigned long id; string IORrob; };

struct InstantaneaD{ sequence<EstadoRobotD> estadorobs; }; };

module robot{ interface RobotSeguidorInt{ void ObtenerEstado(out corba::instantanea::EstadoRobotD est); };

};

module camara{

struct IPYPortD{ string ip; unsigned long port; };

struct suscripcionD{ unsigned long id; IPYPortD iport; };

interface CamaraInt{ suscripcionD SuscribirRobot(in string IORrob); }; };};

5.4.3.- Proyecto prj-camara

Fichero camara/CamaraServerimpl.java

package camara;

import comm.*;import corba.instantanea.*;import corba.camara.*;import corba.camara.suscripcionD;import corba.camara.IPYPortD;import corba.robot.*;import java.util.LinkedList;import java.util.Iterator;

65

Page 70: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

public class CamaraIntServerImpl extends corba.camara.CamaraIntPOA {

private org.omg.PortableServer.POA poa_; private org.omg.CORBA.ORB orb_;

private LinkedList listaRobots = new LinkedList(); private LinkedList listaEstados = new LinkedList(); InstantaneaD instantanea; private int nrobots; private IPYPortD ipyport;

public

CamaraIntServerImpl(org.omg.CORBA.ORB orb, org.omg.PortableServer.POA poa, IPYPortD iport) { orb_ = orb; poa_ = poa; ipyport = new IPYPortD(iport.ip, iport.port); nrobots = 0; }

public org.omg.PortableServer.POA _default_POA() { if(poa_ != null) return poa_; else return super._default_POA(); }

// // IDL:corba/Camara/CamaraInt/SuscribirRobot:1.0 // public suscripcionD SuscribirRobot(String IORrob) {

// TODO: implement

//EJERCICIO: Implementar la suscripcion al robot }

//------------------------------------------------------------------------------ // La clase anidada CamaraDifusion //------------------------------------------------------------------------------ class CamaraDifusion extends Thread{ private Difusion difusion; //------------------------------------------------------------------------------ public CamaraDifusion(IPYPortD iport){ difusion = new Difusion(iport);

66 Difusión y grupos dinámicos: la agencia

Page 71: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

}

//------------------------------------------------------------------------------ public void run(){ corba.instantanea.EstadoRobotDHolder st = new EstadoRobotDHolder(); String ior=null; LinkedList listaFallos = new LinkedList();

while(true){ listaEstados.clear(); listaFallos.clear(); for (Iterator i = listaRobots.iterator(); i.hasNext(); ){ try {

//EJERCICIO: invocar via CORBA el metodo ObtenerEstado y anyadir

//el estado del robot correspondiente a la lista de estados

} catch (/*EJERCICIO: Seleccionar excepcion */ e){ System.out.println("Detectado fallo 4 Robot: " + ior );

//EJERCICIO: anyadir el robot caido a la lista de fallos } }

//EJERCICIO: crear una instantanea a partir de la lista de estados de los robots. instantanea = new InstantaneaD(/*EJERCICIO*/);

//EJERCICIO: difundir la instantanea try{ Thread.sleep(400); }catch(InterruptedException e){ e.printStackTrace(); } } } }}

Fichero camara/Server_AOM.modif

package camara;

/*MODIFICADO*/import corba.camara.*;/*FIN MODIFICADO*/

/*MODIFICADO*/private static corba.camara.IPYPortD ipyport;/*FIN MODIFICADO*/

/*MODIFICADO*/if (args.length>=2) ipyport = new IPYPortD( args[0], Integer.parseInt(args[1]) );else ipyport = new IPYPortD( "228.7.7.7", 7010);System.out.println("Difusión por canal. " + ipyport.ip + " / " + ipyport.port);

67

Page 72: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

/*FIN MODIFICADO*/ // Create the servant/*MODIFICADO*/CamaraIntServerImpl servant = new CamaraIntServerImpl(orb,poa,ipyport);/*FIN MODIFICADO*/

/*FIN MODIFICADO*/servant.start();/*FIN MODIFICADO*/

5.4.4.- Proyecto prj-robot

Fichero robot/RobotSeguidorIntServerImpl.java

package robot;

import corba.instantanea.EstadoRobotDHolder;

import comm.*;import corba.instantanea.*;import corba.camara.*;

/** * This class is the implementation object for your IDL interface. * * Let the Eclipse complete operations code by choosing 'Add unimplemented methods'. */public class RobotSeguidorIntServerImpl extends corba.robot.RobotSeguidorIntPOA {

org.omg.CORBA.ORB orb; CamaraInt camara;

String minombre; int miid; String miIOR; private InstantaneaD instantanea; /** * Constructor for RobotSeguidorIntServerImpl */public RobotSeguidorIntServerImpl() {}

public void ObtenerEstado(EstadoRobotDHolder est) {

// TODO Auto-generated method stub

//EJERCICIO: componer la instantanea a partir de EstadoRobotD y retornarla

corba.instantanea.EstadoRobotD _r = /*EJERCICIO*/; //return _r; est.value = _r; // new corba.instantanea.EstadoRobotD();

68 Difusión y grupos dinámicos: la agencia

Page 73: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

}

public void start(){ new RobotDifusion().start(); }

//------------------------------------------------------------------------------ // La clase anidada RobotDifusion //------------------------------------------------------------------------------

class RobotDifusion extends Thread{

private Difusion difusion; private EstadoRobotD sr; private suscripcionD sus;

public void run(){

//EJERCICIO: suscribir el robot en la camara

//EJERCICIO: crear la difusion

miid=sus.id;

while(true){

//EJERCICIO: recibir instantanea

//EJERCICIO: iterar sobre la lista de estados, imprimiendo el nombre de

//todos los robots cuyo estado figura en la instantanea. System.out.println("Robot " + i + " : " + sr.nombre); }

try{ Thread.sleep(400); }catch(InterruptedException e){ e.printStackTrace(); } } } }}

Fichero robot/Server_AOM.modif

package robot;

/*MODIFICADO*/import corba.camara.*;/*FIN MODIFICADO*/

/*MODIFICADO*/

69

Page 74: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

static CamaraInt camara; static int ok=0; /*FIN MODIFICADO*/

/*MODIFICADO*/ do{ try{

//EJERCICIO:Conectar con el servidor de nombre y obtener una referencia

//a la **camara**

System.out.println("Identificador: " + servant);

//EJERCICIO: convertir la referencia al robot en un IOR en formato String

servant.miIOR = /*EJERCICIO*/; servant.orb = orb; servant.camara = camara; if (args.length>0) servant.minombre = args[0]; else servant.minombre="Robot"; ok=1; } catch(Exception ex) { System.out.println("El robot no se registro bien en la camara. Reintentando..."); } } while(ok==0);

servant.start(); /*FIN MODIFICADO*/

70 Difusión y grupos dinámicos: la agencia

Page 75: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

PRÁCTICA 6 El applet echo

DYA

l objetivo de esta práctica es realizar un applet para un cliente de echo, es decir un

cliente de echo cuya interfaz gráfica (GUI) se proporcione sobre un navegador web

y sea similar a la especificada en la figura 1 (pág. 71).,

FIGURA 1. Estructura de la aplicación

E

71

Page 76: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Estructura de la aplicación

Esta interfaz gráfica o GUI’s (Grafical User Interface) deberá generarse con un editor visual de

interfaces incorporada en el entorno de desarrollo (IDE) de Java.

El funcionamiento del applet de echo es el siguiente: envía a la máquina especificada en el campo

Host, la cadena del campo String to send y cuando se recibe la respuesta del servicio de echo, la

representa en el campo String received. El envío de la cadena se realiza cuando se produce alguno

de los siguientes eventos:

• Evento 1: Se aprieta el botón SEND

• Evento 2: Se proporciona un <CR> en String to send

Este cliente deberá funcionar con los servidores de echo realizados en prácticas anteriores que se

especifican:

• Servidor de echo con sockets: conectará con este servidor al producirse al producirse el evento 1

• Servidor de echo RMI (o CORBA): conectará con este servidor al producirse al producirse el

evento 2

IMPORTANTE: es necesario que tenga a punto los proyectos de las prácticas de sockets y RMI

antes de empezar a realizar esta práctica.

6.1.- Estructura de la aplicaciónEsta aplicación consta de dos paquetes: el paquete con la interfaz del servicio en RMI (pac-

kage rmi) y el paquete cliente (package client). Como paquete sevidor se utilizarán directamente los

paquetes con la parte servidora del servicio de echo desarrollados en las prácticas de sockets y RMI.

6.1.1.- La interfaz rmi

Contiene la interfaz RMI del servicio de echo. Consta del siguiente fichero:

• EchoInt.java: el mismo interfaz del servicio de echo que el de las prácticas de sockets y RMI

72 El applet echo

Page 77: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de la parte básica de la práctica

DYA

6.1.2.- El paquete client

Lo conforma la parte cliente del servicio de echo. Consta de un fichero con el stub del

cliente del servicio basado en sockets y el applet:

• EchoObjectStub.java: es el stub del servicio de echo basado en sockets utilizado en prácticas

anteriores. Este stub estaba generado “a mano” y se encuentra ya totalmente terminado de prác-

ticas anteriores.

• EchoApplet.java: es el applet con el cliente del servicio de echo, objeto de esta práctica. Con-

tiene una interfaz gráfica para dicho servicio que puede visualizarse en un navegador web. No se

proporciona plantilla alguna para este fichero, ya que deberá generarse íntegramente a partir de

un editor gráfico de interfaces (GUI’s).

6.2.- Realización de la parte básica de la prácticaPara la realización de la parte básica de la práctica comience por crear un proyecto, descar-

gar los ficheros de apoyo y añadirlos al proyecto. Posteriormente desarrolle el applet echo con un

editor gráfico. De una manera más detallada, los pasos a seguir se detallan en los siguientes aparta-

dos.

6.2.1.- Creación del proyecto

Este abaratado consta de los mismos pasos que las prácticas anteriores:

1. Descargue los ficheros de ayuda al directorio de descargas.

2. Cree un proyecto prj-applet en el workspace cree también los paquetes de que consta la aplica-ción: rmi, client.

3. Copie los ficheros de apoyo desde el directorio de descargas al workspace.

6.2.2.- Realización del applet echo

La realización de un applet consta, fundamentalmente de dos pasos:

1. Desarrollo de la interfaz gráfica (GUI)2. Realización de los manejadores de eventos.

Cada uno de estos pasos se detalla a continuación.

73

Page 78: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de la parte básica de la práctica

Desarrollo de la interfaz gráfica (GUI)1. Añada al paquete client del proyecto un nuevo fichero, denominado EchoApplet.java, con la

opción New -> Other -> Java -> Visual Class, especificando:- Superclass: javax.swing.JApplet

Observe que se crea una plantilla de un fichero con un applet y se ofrece una doble visión del

mismo: código fuente y diseño gráfico. Ver figura 2 (pág. 74).

Inicialmente aparece el contenedor del applet vacío. Para realizar el diseño de una interfaz gráfica

como la mostrada en la figura 1 (pág. 71) deberá ir añadiendo elementos de la Palette de compo-

nentes gráficos. Deberá tener en cuenta los siguientes aspectos:

2. Seleccionar el Layout Manager null. Para ello, seleccione el contenedor, observe la ventana deProperties y modifique adecuadamente la propiedad layout.

3. Añada componentes gráficos seleccionándolos desde el menú de Swing Components de laPalette. Se recomienda dar a los componentes nombres fácilmente identificables (Property ->name) en el momento de su creación, especialmente aquellos que vayan a ser manipulados:- botonEnviar

- textoHost

- textoEnviar

- textoRecibido

FIGURA 2. El editor gráfico en el IDE Eclipse

74 El applet echo

Page 79: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de la parte básica de la práctica

DYA

- barraEstado

Realización de los manejadores de eventosSe realizarán manejadores para los siguientes eventos de tipo ActionEvent:

• Pulsación del botón SEND: el manejo consistirá en solicitar el servicio de echo vía sockets.

• Teclear <CR> en el campo de texto etiquetado como String to send: el manejo consistirá en soli-

citar el servicio de echo al servidor RMI (o CORBA) correspondiente.

Para realizar un manejador de un componente gráfico:

1. Seleccione el componente en el editor gráfico y apriete el botón derecho del ratón. En el menúcontextual seleccionar Events -> ActionPerformed. Se creará en la ventana de código lasiguiente plantilla de manejador:jButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent e) { System.out.println("actionPerformed()");

// TODO Auto-generated Event stub actionPerformed() } );

2. Rellene la plantilla del manejador con el código que corresponda a cada manejador.

En el caso del evento del botón, el código consiste en invocar el servicio de echo de sockets

mediante el stub EchoObjectStub. El código se proporciona a continuación (observe en font dife-

rente los nombres dados a los componentes gráficos):

EchoObjectStub es = new EchoObjectStub(); String host = new String(textoHost.getText()); String input = new String(textoEnviar.getText()); String output = new String("Error!"); try { es.setHostAndPort(host,7); output = es.echo(input); textoRecibido.setText(output); } catch (RemoteException x) { barraEstado.setText("No se pudo comunicar con el server"); }

Realice un manejador semejante para el caso del evento del campo de texto textoEnviar, realizando

en este caso una invocación al servicio de echo RMI (o CORBA).

6.2.3.- Ejecución de la aplicación

Para la ejecución de la aplicación, realice los siguientes pasos:

75

Page 80: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ejecución del applet echo como aplicación web

1. Abra los proyectos prj-sockets y prj-rmi realizados en prácticas anteriores, y ponga en ejecuciónlos servidores correspondientes

2. Ejecute el cliente de echo con el menú Run... Java Applet. Se ejecutará el applet en una aplica-ción AppletViewer que permite comprobar su funcionamiento básico antes de acudir al navega-dor web.

6.3.- Ejecución del applet echo como aplicación webPara ejecutar el cliente del servicio de echo como aplicación web se recomienda el siguiente

proceso:

1. Empaquetar el applet en un fichero JAR.2. Realizar una página HTML para lanzar la aplicación.3. Ubicar la aplicación en una máquina con un servidor web HTTP.4. Resolver los problemas de seguridad que puedan aparecer.

A continuación se examina cada uno de estos pasos con mayor detalle.

6.3.1.- Creación de un archivo JAR con el applet

Para poder ejecutar un applet en un navegador web es conveniente empaquetar y comprimir

todas las clases java de que consta en un archivo JAR, incluyendo todas las clases y bibliotecas que

no se encuentran en el entorno de la máquina virtual del navegador.

La creación del archivo JAR se realiza seleccionando el proyecto y mediante el menú con-

textual de botan derecho indicando la opción Export -> JAR file. Especifique como nombre del

fichero prj-applet.jar.

6.3.2.- Realización de una página HTML para el applet

Consiste en generar una página HTML que referencie el archivo JAR anteriormente creado.

Realice una página EchoApplet.htm en el mismo directorio donde se encuentre el archivo JAR prj-

applet.jar cuyo contenido sea:

<html><head> <title> Página de prueba del applet de echo </title></head><body> El applet client.EchoApplet de Joan Vila debe aparecer debajo en un visualizador de Java.<br>

<applet

76 El applet echo

Page 81: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ejecución del applet echo como aplicación web

DYA

archive = "prj-applet.jar"

code = "client.EchoApplet.class" name = "TestApplet" width = "400" height = "300" hspace = "0" vspace = "0" align = "middle"></applet></body></html>

Para la ejecución del fichero JAR desde un navegador web debe comprobar que el navegador ele-

gido tiene instalado el plug-in de la máquina virtual Java de Sun. Si no esta instalado, debe descar-

garse de http://java.sun.com.

6.3.3.- Ubicación del cliente en un servidor web

Para poder probar el cliente de echo como una aplicación web, debe ubicar el applet en un

directorio servido por un servidor web. Ubique en este directorio los ficheros prj-applet.jar y

EchoApplet.htm. Las posibilidades de que dispone para este directorio son:

• El subdirectorio $HOME/public_html si trabaja en una máquina Unix con servidor web.

- En este directorio el applet se accede con el URL:

http://lamode.disca.upv.es/~USUARIO/EchoApplet.htm

• Un directorio del usuario dya en una máquina que disponga de servidor web. El URL de este

servidor es: http://lamode.disca.upv.es/~dya. Puede ubicar su aplicación en este servidor vía ftp:

ftp://[email protected]/public_html/ (Usuario=dya, Passwd:(el de siempre))

- Cree su propio directorio en esta máquina evitando colisionar con los directorios de sus com-pañeros: ftp://lamode.disca.upv.es/dya/public_html/%USER%

- En este directorio el applet se accede con el URL:

http://futura.disca.upv.es/~dya/USUARIO/client.EchoApplet.html

6.3.4.- Ejecución del applet firmado

Si se ejecuta el applet contra un servicio de echo ubicado en el mismo servidor que el servi-

dor web, funciona correctamente. En este caso no deben existir demasiados problemas de seguridad

puesto que el applet y el servidor de echo se encuentran en la misma máquina.

77

Page 82: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ejecución del applet echo como aplicación web

Si se ejecuta el cliente de echo contra el servidor de echo de su propia máquina o contra el servidor

de alguno de sus compañeros de prácticas, observará en la consola de Java que el applet lanza una

excepción de seguridad.

6.3.5.- Resolución de problemas de seguridad

Los applets son “virus en potencia” y por lo tanto, suelen presentar problemas de seguridad.

En este caso, los problemas más importantes son:

• Acceso al port 1099 requerido por RMI

• Comunicación con “terceros”, es decir, servidores ubicados en máquinas distintas a la máquina

de la que proviene el applet.

A ‘partir de la plataforma Java 2, la forma de habilitar una política de seguridad diferente a

la de defecto es implementar un fichero java.policy que la defina. Este fichero debe habilitarse en el

fichero java.security de la máquina virtual del navegador.

Ubique el fichero java.security y observe que permite la localización de un nuevo fichero

con la política de seguridad, denominado .java.policy, en el directorio de usuario ${user.home}:

# The default is to have a single system-wide policy file,# and a policy file in the user's home directory.policy.url.1=file:${java.home}/lib/security/java.policypolicy.url.2=file:${user.home}/.java.policy

Cree el fichero ${user.home}\.java.policy. (el directorio ${user.home}en Windows es C:/Documents

and Settings/%USER%). Edítelo y añada:

grant { //permission java.security.AllPermission; permission java.net.AllPermission;};

• La ejecución de un applet ubicado en un fichero local requiere el permiso:

permission java.net.AllPermission

• La ejecución de un applet ubicado un servidor web requiere el permiso:

permission java.security.AllPermission

ya que el anterior no cubre la comunicación con “terceros”.

78 El applet echo

Page 83: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ejecución del applet echo como aplicación web

DYA

Elimine el fichero ${user.home}\.java.policy al terminar la práctica, para evitar problemas cuando

visite sitios no seguros.

79

Page 84: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ejecución del applet echo como aplicación web

80 El applet echo

Page 85: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

PRÁCTICA 7 Servlets

DYA

l objetivo de esta práctica es comprender el mecanismo de funcionamiento de los

servlets programando unos ejemplos de generación dinámica de páginas html y

gestión de cookies.

Los servlets son aplicaciones donde el cliente es una página HTML y el servidor es un pro-

grama CGI (Common Gateway Interface) escrito en Java que ejecuta el servidor web. Los

servlets son la respuesta de la tecnología Java a la programación CGI. Son programas que se

ejecutan en un servidor Web y construyen páginas Web dinámicamente. Construir páginas

Web al vuelo es útil por un número de razones:

• La página Web está basada en datos enviados por el usuario. Por ejemplo, las páginas de

resultados de los motores de búsqueda se generan de esta forma, y los programas que

procesan pedidos desde sitios web de comercio electrónico también.

• Los datos cambian frecuentemente. Por ejemplo, un informe sobre el tiempo o páginas

de cabeceras de noticias podrían construir la página dinámicamente, quizás devolviendo

una página previamente construida y luego actualizándola.

E

81

Page 86: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Introducción a servlets

• Las páginas Web que usan información desde bases de datos corporativas u otras fuentes. Por

ejemplo, usaríamos esto para hacer una página Web en una tienda on-line que liste los precios

actuales y el número de artículos en stock.

7.1.- Introducción a servletsLos servlets atienden peticiones realizadas por páginas HTML. Estas peticiones son, funda-

mentalmente, de tipo GET y POST. Las peticiones GET son peticiones hechas por el navegador

cuando el usuario teclea una URL en la línea de direcciones, sigue un enlace desde una página Web,

o rellena un formulario que no especifica un METHOD. Los Servlets también pueden manejar peti-

ciones POST muy fácilmente, que son generadas cuando alguien crea un formulario HTML que

especifica METHOD="POST".

Un servlet es una subclase de HttpServlet y la forma de atender peticiones GET y POST es sobre-

carga doGet o doPost respectivamente. Estos métodos toman dos argumentos: un HttpServle-

tRequest y un HttpServletResponse.

• El HttpServletRequest tiene métodos que nos permiten encontrar información entrante como

datos de un FORM, cabeceras de peticiòn HTTP, etc.

• El HttpServletResponse tiene métodos que nos permiten especificar líneas de respuesta HTTP

(200, 404, etc.), cabeceras de respuesta (Content-Type, Set-Cookie, etc.), y, todavía más impor-

tante, nos permiten obtener un PrintWriter usado para envíar la salida de vuelta al cliente.

Los servlest no forman parte de SDK y, por tanto, de las bibliotecas estándar de Java (paquetes

java.*). Es necesario importar las extensiones javax.servlet (para HttpServlet, etc.), y javax.serv-

let.http (para HttpServletRequest y HttpServletResponse).

En servlets sencillos, la mayor parte del código consiste en sentencias System.out.println() que gen-

eran la página deseada. Los métodos doGet y doPost pueden propagar dos excepciones, por eso es

necesario incluirlas en la declaración. También observamos que tenemos que importar las clases de

los paquetes java.io (para PrintWriter, etc.),

82 Servlets

Page 87: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Descripción de la aplicación

DYA

Una de las mejores características de los servlets Java es que la obtención de parámetros de formu-

larios se maneja automáticamente. Simplemente llamamos al método getParameter de HttpServle-

tRequest, y suministramos el nombre del parámetro como un argumento. Observa que los nombres

de parámetros son sensibles a mayúsculas.

El valor de retorno es un String correspondiente al valor uudecode de la primera ocurrencia del

parámetro. Se devuelve un String vacío si el parámetro existe pero no tiene valor, y se devuelve null

si no existe dicho parámetro. Si el parámetro pudiera tener más de un valor, como en el ejemplo

anterior, deberíamos llamar a getParameterValues en vez de a getParameter. Este devuelve un array

de strings. Finalmente, aunque en aplicaciones reales nuestros servlets probablemente tengan un

conjunto específico de nombres de parámetros por los que buscar. Usamos getParameterNames

para esto, que devuelve una Enumeration, cada entrada puede ser forzada a String y usada en una

llamada a getParameter.

7.2.- Descripción de la aplicaciónEn esta práctica se realizarán dos aplicaciones:

- Servlet1: un servlet elemental y

- CookieServlet: un servlet con cookies.

Ambas aplicaciones constan de un cliente HTML y un servlet que es ejecutado por un servidor web.

7.2.1.- El servlet elemental

En el servlet elemental, el cliente HTML (figura 2 (pág. 84) (a) ) está compuesto por dos

formularios con sendos botones "submit" que realizan peticiones GET ó POST, según el caso, al

servidor web para que ponga en ejecución el servlet Servlet1.class

El servlet, simplemente responde con un mensaje indicando qué método se ha invocado (doGet ó

doPost). El resultado aparece en la figura 2 (pág. 84) (a).

7.2.2.- El servlet con cookies

En el servlet con cookies, el cliente HTML tiene dos formularios (figura 2 (pág. 84)):

83

Page 88: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Descripción de la aplicación

• El primer formulario realiza una petición POST (de HTTP) al servidor web para que ponga en

ejecución el servlet CookieServlet.class y ejecute el método doPost.

• Al ejecutar el método doPost el servlet responde con una página HTML (dinámica) que visual-

iza los cookies que el cliente le pasa en la cabecera de la petición HTTP (figura 3 (pág. 85) (a)).

• El segundo formulario realiza una petición GET (de HTTP) al servidor web para que ponga en

ejecución el servlet CookieServlet.class y ejecute el método doGet.

FIGURA 1. Servlet elemental

FIGURA 2. Servlet con cookies

84 Servlets

Page 89: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de la parte básica de la práctica.

DYA

• Al ejecutar el método doGet el servlet define un nuevo cookie, cuyo nombre y valor se solicitan

en el formulario, y lo envía al cliente web. El servlet esponde con una página HTML (dinámica)

que visualiza el nuevo cookie (figura 3 (pág. 85) (b)).

7.3.- Realización de la parte básica de la práctica.La realización práctica consistirá en el desarrollo y depuración de ambos servlets en el

entorno eclipse. Posteriormente se instalarán los servlets en un servidor Tomcat independiente de

eclipse.

7.3.1.- Instalación de los plug-in para eclipse

Normalmente estos paquetes ya estarán instalados en las máquinas del laboratorio. No

obstante, el procedimiento para instalar los plug-in necesarios para ejecutar los servlets es:

1. Buscar los componentes para la actualización en: - Help->Software updates->Find and Install…

2. Seleccionar "Search for new features to install"3. Seleccionar "Calisto Discovery Site" y pulsar "Finish"4. Seleccionar el Mirror "Calisto Discovery Site"5. Marcar la casilla "Calisto Discovery Site" para seleccionas todos los plug-in del "site". Pulsar

"Next"6. Aceptar la licencia y pulsar "Next"7. Si no se quiere cambiar el directorio de instalación, pulsar "Finish".

FIGURA 3. Respuesta del servlest con cookies

85

Page 90: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de la parte básica de la práctica.

Dependiendo de la velocidad de la conexión a internet este proceso puede tardar desde 5 minutos a

varias horas.

Obsérvese que junto con los plug-in necesarios se han instalado muchos más. Es conveniente reali-

zar esta operación para disponer de un entorno de desarrollo completamente actualizado. En reali-

dad sólo es necesario instalar los plug-in correspondientes a servicios web dentro de la sección de

J2EE y aquellos paquetes de los cuales depende.

7.3.2.- El servlet elemental

8. Creación del proyecto- Cree un nuevo proyecto con File->New->Project

- Seleccione el tipo de proyecto Web->Dynamic Web Project

- Asigne un nombre al proyecto (p.e. pr07_servlet)

- Seleccione el "Target Runtime" como "Apache Tomcat v5.5"

- Next, Next y Finish

- Por defecto eclipse ofrecerá una perspectiva J2EE

9. Creación del esqueleto del servlet- Cree en el proyecto un nuevo paquete llamado servlets (New->package)

- Cree un nuevo servlet llamado Servlet1 (New->Other->Web->Servlet)

10. Modifique los métodos doGet y doPost para que respondan como indica la figura 2.11. Ejecute el servlet Run As->Run on server12. Pruebe a ejecutarlo desde un cliente web escribiendo la url:

- http://localhost:8080/pr07_servlet/Servlet1

13. Invocar a los métodos desde una página web- Edite el fichero Servlet1.html realizando los ejercicios propuestos

- Abra el fichero con un navegador web

7.3.3.- El servlet con cookies

14. Edite el fichero CookieServlet.java: - Cree un nuevo servlet llamado CookieServlet (New->Other->Web->Servlet)

- Modifique el método doGet para que el servlet defina un nuevo cookie, cuyo nombre y valorse solicitan en el formulario, y lo envía al cliente web. El servlet esponderá con una páginaHTML (dinámica) que visualiza el nuevo cookie (figura 3 (pág. 85) (a)).

86 Servlets

Page 91: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Realización de la parte básica de la práctica.

DYA

- Modifique el método doPost el servlet responda con una página HTML (dinámica) que visu-aliza los cookies que el cliente le pasa en la cabecera de la petición HTTP (figura 3 (pág. 85)(b)).

15. Ejecute el servlet Run As->Run on server16. Pruebe a ejecutarlo desde un cliente web escribiendo la url:

- http://localhost:8080/pr07_servlet/ CookieServlet

17. Invocar a los métodos desde una página web- Edite el fichero cookieservlet.html:

18. Modifique el código fuente en HTML de esta página para visualizar el formulario requerido y,especialmente, el URL del servlet.- Abra el fichero con un navegador web

7.3.4.- Instalación y ejecución sobre Tomcat

Instalación de Tomcat19. Descargue la distribución de tomcat V5.5: apache-tomcat-5.5.20.zip (~6.6Mb)20. Descomprímala en un directorio de su máquina que llamaremos de ahora en adelante

%CATALINA_HOME%- Nota: Descomprimaló de forma que el directorio %CATALINA_HOME%\bin exista

21. Escriba un script (.bat) para establecer las variables de entorno CATALINA_HOME yJRE_HOME. Por ejemplo:

set JRE_HOME="C:\jre1.5.0_08"

set CATALINA_HOME=C:\dya0607\apache-tomcat-5.5.20

- Nota: Es importante que JRE_HOME no contenga espacios en blanco.

22. Invoque el script para establecer las variables de entorno23. Para arrancar tomcat invocar: %CATALINA_HOME%\bin\startup

- Antes de arrancar compruebe que Tomcat no está en funcionamiento dentro del entornoeclipse.

- Compruebe el funcionamiento de Tomcat accediendo con un navegador web a http://local-host:8080

24. Para detener tomcat invocar: %CATALINA_HOME%\bin\shutdown

Instalación de servlets sobre Tomcat25. Crear un directorio para la aplicación en %CATALINA_HOME%\webapps\pr07_servlet

87

Page 92: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ampliaciones de la práctica

26. Copie el contenido del directorio Webcontent del proyecto eclipse (directorios META-INT yWEB-INF) al directorio que se ha creado en Tomcat para la aplicación.- Nota: Es especialmente importante el fichero web.xml. Revise su contenido para comprender

el funcionamiento de Tomcat.

27. Copie las clases generadas con eclipse (Servlet1.class y CookieServlet.class) al directorio%CATALINA_HOME%\webapps\pr07_servlet\WEB-INF\classes\servlets- Nota: Observe que el último directorio de la ruta (servlets) hace referencia al nombre del

paquete al que pertenecen las clases.

28. Copie los archivos html de acceso a los servlets (Servlet.html y cookieservlet.html) a la ruta:%CATALINA_HOME%\webapps\pr07_servlet

29. Arranque Tomcat30. Acceda a los archivos html con un navegador web especificando la url:

- http://localhost:8080/pr07_servlet/Servlet.html

- http://localhost:8080/pr07_servlet/cookieservlet.html

7.4.- Ampliaciones de la prácticaComo ampliación al trabajo realizado en la práctica se propone poner en funcionamiento,

probar y comprender tres servlets distintos correspondientes al código fuente de las tres clases que

se adjuntan:

• ShowParameters.java

• ShowRequestHeaders.java

• ShowCGIVariables.java

Para compilar estos ejemplos es necesario incluir la clase ServletUtilities.java.

El primer ejemplo permite visualizar Todos los parámetros con los que el cliente html ha invocado

al servlet. El segundo ejemplo visualiza las cabeceras http con las que el navegador ha invocado al

servlet. El tercer ejemplo visualiza las variables CGI que incluyen información sobre la petición.

Observe que para que funcionen los ejemplos hay que editar el archivo web.xml correspondiente

para incluir las secciones necesarias del tipo “servlet” y “servlet mapping”. Para hacerlo, inspec-

cione el archivo web.xml generado automáticamente por el entorno eclipse en la parte elemental de

la práctica. En aquella ocasión, el entorno eclipse introdujo las secciones necesarias como parte del

88 Servlets

Page 93: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

proceso de creación de un servlet (New->Other->Web->Servlet). En este caso, como hemos aña-

dido los ficheros de apoyo al proyecto hay que definir estas secciones manualmente.

7.5.- Ficheros de apoyo

7.5.1.- Ficheros para la parte básica de la práctica

Fichero Servlet.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Insert title here</title></head><body>

<form action="//EJERCICIO!!! escribir la url del servlet" method="get"><p>Pulsa Submit para invocar GET del servlet Servlet1</p><p><input type="submit" name="Submit" value="Submit"><input type="reset" value="Reset"></p></form>

<br><br><br>

<form action="//EJERCICIO!!! escribir la url del servlet" method="post"><p>Pulsa Submit para invocar POST del servlet Servlet1</p><p><input type="submit" name="Submit" value="Submit"><input type="reset" value="Reset"></p>

</form></body></html>

Fichero cookieservlet.html

<html><head><title>CookieServlet</title></head><body bgcolor="#ffffff">

89

Page 94: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

<FORM action="//EJERCICIO!!! escribir la url del servlet" method="post"><h1> Obtener lista de los cookies con los que se está haciendo la petición</h1><input type=submit value="Submit"></form><br><br><br>

<form action="//EJERCICIO!!! escribir la url del servlet" method="get"><h1>Pulsar Submit para definir un nuevo cookie.</h1><p>Nombre <input type="text" name="Nombre"></p><p>Valor <input type="text" name="Valor"></p><p><input type="submit" name="Submit" value="Submit"><input type="reset" value="Reset"></p>

</form></body></html>

Fichero esqueleto_de_un_servlet.java

package servlets;

import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;

/** * Servlet implementation class for Servlet: Servlet1 * */ public class Servlet1 extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { /* (non-Java-doc) * @see javax.servlet.http.HttpServlet#HttpServlet() */public Servlet1() {super();}

/* (non-Java-doc) * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, * HttpServletResponse response) */

protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {

// TODO Auto-generated method stub}

/* (non-Java-doc) * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request, * HttpServletResponse response) */protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

90 Servlets

Page 95: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

// TODO Auto-generated method stub} }

7.5.2.- Ficheros para las ampliaciones

Fichero ServletUtilities.java

package hall;

import javax.servlet.*;import javax.servlet.http.*;

public class ServletUtilities {

public static final String DOCTYPE = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">";

public static String headWithTitle(String title) { return(DOCTYPE + "\n" + "<HTML>\n" + "<HEAD><TITLE>" + title + "</TITLE></HEAD>\n"); }

public static int getIntParameter(HttpServletRequest request, String paramName, int defaultValue) { String paramString = request.getParameter(paramName); int paramValue; try { paramValue = Integer.parseInt(paramString); } catch(NumberFormatException nfe) { // null or bad format paramValue = defaultValue; } return(paramValue); }}

Fichero ShowParameters.java

package hall;

import java.io.*;import javax.servlet.*;import javax.servlet.http.*;import java.util.*;

public class ShowParameters extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

91

Page 96: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

response.setContentType("text/html"); PrintWriter out = response.getWriter(); String title = "Reading All Request Parameters"; out.println(ServletUtilities.headWithTitle(title) + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + "<TABLE BORDER=1 ALIGN=CENTER>\n" + "<TR BGCOLOR=\"#FFAD00\">\n" + "<TH>Parameter Name<TH>Parameter Value(s)"); Enumeration paramNames = request.getParameterNames(); while(paramNames.hasMoreElements()) { String paramName = (String)paramNames.nextElement(); out.println("<TR><TD>" + paramName + "\n<TD>"); String[] paramValues = request.getParameterValues(paramName); if (paramValues.length == 1) { String paramValue = paramValues[0]; if (paramValue.length() == 0) out.print("<I>No Value</I>"); else out.print(paramValue); } else { out.println("<UL>"); for(int i=0; i<paramValues.length; i++) { out.println("<LI>" + paramValues[i]); } out.println("</UL>"); } } out.println("</TABLE>\n</BODY></HTML>"); }

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}

Fichero ShowRequestHeaders.java

package hall;

import java.io.*;import javax.servlet.*;import javax.servlet.http.*;import java.util.*;

public class ShowRequestHeaders extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

response.setContentType("text/html"); PrintWriter out = response.getWriter();

92 Servlets

Page 97: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

String title = "Servlet Example: Showing Request Headers"; out.println(ServletUtilities.headWithTitle(title) + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + "<B>Request Method: </B>" + request.getMethod() + "<BR>\n" + "<B>Request URI: </B>" + request.getRequestURI() + "<BR>\n" + "<B>Request Protocol: </B>" + request.getProtocol() + "<BR><BR>\n" + "<TABLE BORDER=1 ALIGN=CENTER>\n" + "<TR BGCOLOR=\"#FFAD00\">\n" + "<TH>Header Name<TH>Header Value"); Enumeration headerNames = request.getHeaderNames(); while(headerNames.hasMoreElements()) { String headerName = (String)headerNames.nextElement(); out.println("<TR><TD>" + headerName); out.println(" <TD>" + request.getHeader(headerName)); } out.println("</TABLE>\n</BODY></HTML>"); }

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}

Fichero ShowCGIVariables.java

package hall;

import java.io.*;import javax.servlet.*;import javax.servlet.http.*;import java.util.*;

public class ShowCGIVariables extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

response.setContentType("text/html"); PrintWriter out = response.getWriter(); String[][] variables = { { "AUTH_TYPE", request.getAuthType() }, { "CONTENT_LENGTH", String.valueOf(request.getContentLength()) }, { "CONTENT_TYPE", request.getContentType() }, { "DOCUMENT_ROOT", getServletContext().getRealPath("/") }, { "PATH_INFO", request.getPathInfo() }, { "PATH_TRANSLATED", request.getPathTranslated() }, { "QUERY_STRING", request.getQueryString() }, { "REMOTE_ADDR", request.getRemoteAddr() },

93

Page 98: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

{ "REMOTE_HOST", request.getRemoteHost() }, { "REMOTE_USER", request.getRemoteUser() }, { "REQUEST_METHOD", request.getMethod() }, { "SCRIPT_NAME", request.getServletPath() }, { "SERVER_NAME", request.getServerName() }, { "SERVER_PORT", String.valueOf(request.getServerPort()) }, { "SERVER_PROTOCOL", request.getProtocol() }, { "SERVER_SOFTWARE", getServletContext().getServerInfo() } }; String title = "Servlet Example: Showing CGI Variables"; out.println(ServletUtilities.headWithTitle(title) + "<BODY BGCOLOR=\"#FDF5E6\">\n" + "<H1 ALIGN=CENTER>" + title + "</H1>\n" + "<TABLE BORDER=1 ALIGN=CENTER>\n" + "<TR BGCOLOR=\"#FFAD00\">\n" + "<TH>CGI Variable Name<TH>Value"); for(int i=0; i<variables.length; i++) { String varName = variables[i][0]; String varValue = variables[i][1]; if (varValue == null) varValue = "<I>Not specified</I>"; out.println("<TR><TD>" + varName + "<TD>" + varValue); } out.println("</TABLE></BODY></HTML>"); }

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}

Fichero PostForm.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD> <TITLE>A Sample FORM using POST</TITLE></HEAD>

<BODY BGCOLOR="#FDF5E6"><H1 ALIGN="CENTER">A Sample FORM using POST</H1>

<FORM ACTION="//EJERCICIO!!! escribir la url del servlet" METHOD="POST"> Item Number: <INPUT TYPE="TEXT" NAME="itemNum"><BR> Quantity: <INPUT TYPE="TEXT" NAME="quantity"><BR> Price Each: <INPUT TYPE="TEXT" NAME="price" VALUE="$"><BR> <HR> First Name: <INPUT TYPE="TEXT" NAME="firstName"><BR>

94 Servlets

Page 99: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

Last Name: <INPUT TYPE="TEXT" NAME="lastName"><BR> Middle Initial: <INPUT TYPE="TEXT" NAME="initial"><BR> Shipping Address: <TEXTAREA NAME="address" ROWS=3 COLS=40></TEXTAREA><BR> Credit Card:<BR> <INPUT TYPE="RADIO" NAME="cardType" VALUE="Visa">Visa<BR> <INPUT TYPE="RADIO" NAME="cardType" VALUE="Master Card">Master Card<BR> <INPUT TYPE="RADIO" NAME="cardType" VALUE="Amex">American Express<BR> <INPUT TYPE="RADIO" NAME="cardType" VALUE="Discover">Discover<BR> <INPUT TYPE="RADIO" NAME="cardType" VALUE="Java SmartCard">Java SmartCard<BR> Credit Card Number: <INPUT TYPE="PASSWORD" NAME="cardNum"><BR> Repeat Credit Card Number: <INPUT TYPE="PASSWORD" NAME="cardNum"><BR><BR> <CENTER> <INPUT TYPE="SUBMIT" VALUE="Submit Order"> </CENTER></FORM>

</BODY></HTML>

95

Page 100: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

96 Servlets

Page 101: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

PRÁCTICA 8 Servicios web con SOAP y Eclipse

DYA

l objetivo de esta práctica es invocar e implementar servicios web en Java desde el

entorno Eclipse. La práctica está estructurada en tres partes según se esquematiza

en la figura 1 (pág. 98):

1. Invocación de un servicio web disponible en Internet.2. Realización de un nuevo servicio web.3. Invocación de un servicio web desde otro servicio web.

La primera parte consiste en descubrir la interfaz e invocar un servicio web ya existente en

Internet (al que nos referiremos como servicio currency, de una manera genérica) que pro-

porciona el coeficiente de cambio entre cualesquiera dos monedas.

La segunda parte consiste en realizar un “nuevo” servicio web, denominado eurocalcula-

dora, que calcula el cambio de una cantidad de dinero entre el euro y cualquier otra

moneda. En una primera versión se aplicará un coeficiente de cambio fijo e igual a 1. Esto

proporcionará resultados incorrectos, pero permitirá realizar el desarrollo completo de un

servicio y comprobar su funcionamiento.

La tercera parte de la práctica consiste en modificar el servicio web desarrollado en la

segunda parte para que obtenga el coeficiente de cambio de servicio web descubierto en la

primera parte de la práctica. Se trata de convertir un servicio en un cliente de otro servicio.

E

97

Page 102: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Invocación de un servicio web disponible en Internet

8.1.- Invocación de un servicio web disponible en InternetSe comenzará por crear un proyecto prj-soap que abarcará las tres partes de la práctica. Este

proyecto debe ser de tipo Web -> Dynamic Web project. Se creará también un paquete eurocal,

donde se ubicará todo el código que desarrolle.

Para descubrir un servicio web de cambio de moneda debe seguir los pasos que a continuación se

indican:

1. Importar el servicio: Import -> Web Services -> Web Service. Deberá especificar que debelanzarse el Web Services Explorer que deberá examinar el registro UDDI de XMethods Regis-try.

2. Seleccionar el servicio denominado Currency Convertor.3. Importar el fichero WSDL al workbench del proyecto prj-soap con el nombre CurrencyConver-

tor.wsdl, seleccionando la opción que se indica en la figura 2 (pág. 99). 4. Visualizar el fichero CurrencyConvertor.wsdl y observar la interfaz de este proyecto. La visuali-

zación gráfica de esta interfaz se muestra en la figura 3 (pág. 99) y puede observarse que disponede interfaz HTTP e interfaz SOAP.

5. Probar la interfaz SOAP de este servicio utilizando el Web Services Explorer. Para ello deberáseleccionar en el menú contextual de este fichero Web Services -> Test with Web ServicesExplorer. Una vez seleccionada la interfaz SOAP aparecerá un formulario como el de la figura4 (pág. 100).

FIGURA 1. Estructura del servicio web eurocal

98 Servicios web con SOAP y Eclipse

Page 103: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Invocación de un servicio web disponible en Internet

DYA

En la tercera parte de la práctica necesitará invocar este servicio desde un programa Java. Para ello,

necesitará crear unos stubs a partir del fichero WSDL que permitan realizar la invocación remota

utilizando el protocolo SOAP. Para la creación de estos stubs se requiere:

FIGURA 2. El servicio Currency Convertor del registro de Xmethods.

FIGURA 3. Interfaz del servicio Currency Convertor.

99

Page 104: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Creación de un Servicio web

1. Seleccionar el fichero CurrencyConvertor.wsdl y en el menú contextual utilizar la opción WebServices -> Generate Client. Al final del proceso debe aparecer en el proyecto un paqueteNET.webserviceX.www que debe contener los stubs generados.

8.2.- Creación de un Servicio webLa creación de un servicio web en Eclipse puede realizarse siguiendo dos metodologías:

• Bottom up: partiendo de un objeto Java (Java bean)

• Top down: partiendo de una especificación en WSDL.

En esta práctica se utilizara el desarrollo top down en el que se partirá del fichero de especificación

del servicio en WSDL. Consta de los siguientes pasos:

1. Añadir al paquete eurocal un fichero WSDL denominado eurocal.wsdl: New-> Other -> WebServices -> WSDL.

2. Utilizar la interfaz gráfica de este fichero para especificar una interfaz del servicio como la de lafigura 5 (pág. 101).

3. Generar los bindings o vínculos del servicio con las url donde se presta el servicio: GenerateBinding Context.

4. Generar el servicio web. Para ello se debe seleccionar el fichero con la interfaz WSDL (euro-cal.wsdl) y en el menú contextual utilizar la opción Web Services -> Generate java bean ske-leton. Al final del proceso debe aparecer en el proyecto un paquete org.example.www.eurocal

FIGURA 4. Prueba del servicio Currency Convertor con el Web Services Explorer

100 Servicios web con SOAP y Eclipse

Page 105: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Invocación de servicios web desde programas en Java

DYA

que debe contener las plantillas del servicio y el esqueleto para su ejecución como servidorremoto con el protocolo SOAP.

Al final de la generación del servicio se requerirá arrancar el servidor Jakarta Tomcat para ejecutar

el servicio. Si se decide no arrancarlo en este momento, también puede ejecutarse un servicio web

sobre este servidor utilizando la opción Run as -> Run on server. Aparece una ventana en la parte

inferior del IDE denominada Server en la que se indica los servicios que está ejecutando el servi-

dor. Se puede seleccionar alguno de estos servicios y borrarlo.

La implementación del servicio se realiza en el fichero EurocalSOAPImpl.java del paquete

org.example.www.eurocal. Cada vez que se realiza una modificación en este fichero y se salva, se

regenera el servicio web y se rearranca el servidor Jakarta Tomcat para actualizar dicho servicio.

Esta fase de la práctica terminará con la prueba de dicho servicio. Ello requiere:

5. Seleccionar en el menú contextual del fichero Web_Content/wsdl/eurocalSOAP.wsdl la opciónWeb Services -> Test with Web Services Explorer.

8.3.- Invocación de servicios web desde programas en JavaEn esta parte de la practica se indica como el servicio web eurocal puede invocar el servicio

web currency (actualmente se utiliza Currency Convertor) para obtener el coeficiente de cambio

entre el euro y cualquier otra moneda.

La técnica es semejante a los demás mecanismos de invocación remota vistos con anterioridad

(Java-RMI y CORBA): a partir del fichero de especificación del servicio en WSDL se generan los

stubs necesarios par canalizar la invocación remota sobre el protocolo SOAP.

FIGURA 5. Interfaz WSDl del servicio eurocal

Generate Binding Context

101

Page 106: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

Este paso ya se realizó en la primera parte de esta práctica (seleccionar el fichero CurrencyConver-

tor.wsdl y en el menú contextual utilizar la opción Web Services -> Generate Client). El resultado

es un paquete NET.webserviceX.www con los stubs generados. Los ficheros mas significativos son:

• CurrencyConvertorSoap.java: es el stub de la clase correspondiente al servicio.

• Currency.java: es una clase que enumera las diferentes monedas.

• CurrencyConvertorLocator.java: clase que sirve para obtener ubicar y obtener una referencia al

stub del servicio.

Solo resta realizar la invocación remota desde el servicio eurocal. Para ello debe modificar el

fichero EurocalSOAPImpl.java del paquete org.example.www.eurocal tal como se indica a conti-

nuación.

8.4.- Ficheros de apoyo

8.4.1.- Fichero de implementación del servicio SOAP en Java

Fichero EurocalSOAPImpl.java

package org.example.www.eurocal;

import javax.xml.rpc.ServiceException;

import NET.webserviceX.www.Currency;import NET.webserviceX.www.CurrencyConvertorLocator;import NET.webserviceX.www.CurrencyConvertorSoap;

public class EurocalSOAPImpl implements org.example.www.eurocal.Eurocal_PortType{

CurrencyConvertorLocator service;

CurrencyConvertorSoap stub;

public EurocalSOAPImpl() {

service = new CurrencyConvertorLocator();

try {

stub = service.getCurrencyConvertorSoap();

} catch (ServiceException e) {

e.printStackTrace();

}

}

102 Servicios web con SOAP y Eclipse

Page 107: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

DYA

public double convertirAEuros(java.lang.String codi, double moneda) throws java.rmi.RemoteException {

double rate = stub.conversionRate(Currency.fromString(codi), Currency.EUR);

return (moneda*rate); }

public double convertirEuros(java.lang.String codi, double euros) throws java.rmi.RemoteException {

double rate = stub.conversionRate(Currency.EUR, Currency.fromString(codi));

return (euros*rate); }

}

103

Page 108: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Ficheros de apoyo

104 Servicios web con SOAP y Eclipse

Page 109: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

PRÁCTICA 9 Seguridad

DYA

sta práctica consta de dos partes.

La primera parte consiste en la creación y ejecución de un applet firmado.

La segunda parte consiste en la utilización del protocolo Secure Sockets Layer SSL en la

web (protocolo https) mediante la técnica de tunneling.

9.1.- Applets firmadoEl objetivo de esta parte de la práctica es resolver los problemas de seguridad para

ejecución de applets, los cuales requieren permisos más amplios que los permisos por

defecto de la plataforma Java.

En particular la práctica pretende eliminar los problemas de seguridad surgidos con

la ejecución en web del cliente del applet de echo mediante la firma del applet con un certi-

ficado de seguridad.

E

105

Page 110: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

Applets firmado

9.1.1.- El entorno de trabajo

Esta práctica no se realizará con el entorno Eclipse sino con la herramientas keytool y jar-

signer del JDK. Para ello habrá que abrrir un intérprete de comandos en el que habrá que establecer

la variable PATH adecuadamente:

SET PATH= Directorio de Java/bin

Se partirá de un fichero JAR con el applet realizado en la práctica de introducción a los

applets. Denominaremos este fichero prj-applet.jar y a su correspondiente página HTML

EchoApplet.html. Si no dispone de estos ficheros realizados en la práctica anterior, puede utilizar

los del fichero zip de apoyo a esta práctica.

Para la utilización de applets firmados se restablecerá la política de defecto de la plataforma

Java. Para ello, borre el ficheros .java.policy del directorio $HOME (C:\Documents and Set-

tings\usuario en Windows) realizado en la práctica de applets, en el que se concedía todo tipo de

permisos a todas las aplicacione java.

9.1.2.- Creación de un JAR firmado

Los pasos a seguir para firmar el applet son:

1. Generar un almacén de firmas, denominado jvstore, con una entrada denominada firma1 queserá la que servirá para firmar el fichero JAR. Se solicitarán dos claves: una para el almacén defirmas y la otra como clave secreta de la firma. Pueden ser ambas la misma. También se solicita-rán los datos personales del firmante. keytool -genkey -alias firma1 -keystore jvstore

2. Firmar el fichero JAR. El fichero resultante se denominará sprj-applet.jar. jarsigner -keystore jvstore -signedjar sprj-applet.jar prj-applet.jar firma1

3. Crear una página HTML, denominada SEchoApplet.html, para referenciar el fichero sprj-applet.jar.

4. Extraer el certificado del almacén de firmas (exportar) y depositarlo en un fichero .cer. Este cer-tifcado contiene la clave publica del emisor de la firma. keytool -export -keystore jvstore -alias firma1 -file JoanVila.cer

9.1.3.- Verificación de un JAR firmado

Puede verificar un fichero JAR firmado. Esta labor normalmente la realiza el que recibe un

fichero JAR firmado y consta de los siguientes pasos:

1. Observar los datos del certificado. En Windows simplemente hay que pincharlo. En cualquiercaso simpre se puede utilizar

106 Seguridad

Page 111: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

El protocolo SSL y la técnica de tunneling

DYA

keytool -printcert -file JoanVila.cer

2. Importar el certificado y guardarlo en un almacen denominado receptorstore como una entradcon nombre unafirma: keytool -import -alias unafirma -file JoanVila.cer -keystore receptorstore

3. Verificar la firma del JAR: jarsigner -verify -verbose -keystore receptorstore sprj-seguridad.jar

9.1.4.- Ejecución del applet firmado

Para la ejecución del applet firmado deberá ubicarlo en un directorio atendido por un servi-

dor web según se explica en el apartado 6.3.3.- (pág. 77). Posteriormente deberá accederlo mediante

su URL correspondiente.

Con un applet firmado no deberían aparecer ya problemas de seguridad con el applet firmado. En

cualquier caso, si tiene problemas en la invocación RMI, revise los ficheros java.security y

java.policy.

En el directorio doc del fichero zip de apoyo a esta práctica encontrará información detallada de

como configurar estos ficheros. también puede utilizar la herramienta policytool.

9.2.- El protocolo SSL y la técnica de tunnelingEl entorno de trabajo en esta práctica son la herramientas stunnel y openssl disponibles en

las distribuciones habituales de Linux. No obstante también existen versiones para Windows.

En principio, los programas que deseen utilizar SSL deberían modificar su código para utilizar las

funciones de la biblioteca SSL. Para evitarlo se propuso realizar esto mediante tunneling (figura 6

(pág. 108)). Esto permite añadir la capa SSL utilizando un proceso externo que haga de proxy (wra-

pper) entre la red y un servidor no seguro. Suforma de operar es similar al portforwarding de SSH..,

La utilidad stunnel fué diseñada para ofrecer la seguridad SSL a servidores (demonios) o clientes

que no han sido programados con soporte SSL. Puede actuar en la parte del cliente o en la parte del

servidor.

107

Page 112: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

El protocolo SSL y la técnica de tunneling

9.2.1.- stunnel como cliente

Al igual que con socket podemos conectarnos a cualquier puerto de cualquier ordenador conectado

a internet:

$socket www.upv.es 80GET / HTTP/1.0Nos retorna la página principal de la UPV.

Con la siguiente orden se consigue el mismo resultado, pero utilizando una conexión segura.

$ /usr/sbin/stunnel conf-cli$ GET / HTTP/1.0

El fichero conf-cli debe ser configurado del siguiente modo:

client = yesconnect = www.upv.es:443# el puerto estandar de http seguro es el 443 (ver /etc/services).

9.2.2.- stunnel como servidor

La siguiente orden deja en ejecución en segundo plano (background) un servidor stunnel

proporcionando tunneling al port 9500 y utilizando para encriptar el certificado del fichero ser-

ver.pem. En este port se propocionará la salida de la orden $ ls -l.

$ stunnel conf-ser2

El fichero conf-ser2 debe ser configurado del siguiente modo:

cert = /home/usuarios/jvila/ssl/server.pem#key = /home/usuarios/jvila/ssl/server.pem#debug = 1foreground = yespid =#outfile = /tmp/error

FIGURA 6. Técnica de tunneling

108 Seguridad

Page 113: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

El protocolo SSL y la técnica de tunneling

DYA

#local = futura.disca.upv.es[lsd]accept = 9500 exec = /bin/lsexecargs = ls -lpty = yes

Una cuestión importante es que la clave privada a partir de la cual se crea el certificado server.pem

no debe estar protegida con password para que el servidor (web) pueda hacer uso de ella para

encriptar la información:

• El fichero con el certificado deben contener primero la clave privada (sin password), seguido del

certificado.

• Tras la clave privada y el certificado debe aparecer una línea en blanco.

• Por tanto, al fichero creado por la orden:

$ openssl req new x509 nodes keyout server.pem out server.pem

se le ha de han de añadir un retorno de carro después de la clave privada y otro al final (despuésdel certificado).

otra cuestión interesante puede ser la conversión de certificados creados en el entorno Java a certifi-

cados pem. Los certificados de Java son DER codificados en X.509 y no en ASN.1. Esta conversión

puede realizarse con:

$ openssl x509 -inform DER -outform PEM -in JoanVila.cer -out JoanVila.pem

109

Page 114: Prácticas de Diseño y Aplicaciones de Sistemas … · Utilización del servicio de nombres CORBA 44 La plataforma Orbacus 46 Ficheros de apoyo 49 PRÁCTICA 5 Difusión y grupos

El protocolo SSL y la técnica de tunneling

110 Seguridad