Programación en castellano
-Tutoriales

Java IDL


El Ejemplo Cliente-Servidor Hello

Este tutorial enseña las tareas básicas para construir aplicaciones distribuidas CORBA usando Java IDL. Construirmeos el clásico programa Hello World como una aplicación distribuida, con un applet y una aplicación clientes. El programa Hello World tiene una sóla operación que retorna un string a imprimir. La terminología CORBA y sus funcionalidades se explican en La Arquitectura CORBA. El diagrama de la aplicación se repite aquí, junto con una revisión de los pasos del proceso de comunicación entre el cliente y el servidor.

Comunicación entre el cliente y el servidor
  1. El cliente (applet o aplicación) invoca la operación sayHello del HelloServer.
  2. El ORB transfiere la invocación del objeto sirviente registrado para ese interface IDL.
  3. El método sayHello del sirviente, se ejecuta, devolviendo un String Java.
  4. El ORB transfiere ese String de vuelta al cliente.
  5. El cliente imprime el valor del String.

A pesar del diseño sencillo, el programa Hello World nos permite aprender y experimentar con todas las tareas requeridas para desarrollar casi cualquier programa CORBA que use invocación estática.

. Empezando

Antes de empezar a trabajar con Java IDL, necesitamos dos cosas: la versión 1.2 del JDK y el compilador idltojava. El JDK proporciona el API y ORB necesarios para permitir la interacción con objetos distribuidos basados en CORBA. El compilador idltojava usa el mapero IDL-a-Java para convertir las definiciones de interfaces en sus correspondinetes interfaces, clases y métodos Java, que podremos usar para implementar el código de nuestros cliente servidor. Pulsa aquí para descargar e instalar el compilador idltojava

. Escribir el Inteface IDL

En esta sección, escribiremos un sencillo interface IDL para el programa Hello world. El interface IDL define el contrato entre las partes cliente y servidor de nuestra aplicación, especificando qué operaciones y atributos están disponibles. IMG IDL es independiente del lenguaje de programación. Debemos mapearlo a Java antes de escribir cualquier código de implementación. (Ejecutando idltojava sobre el fichero IDL hará esto por nosotros automáticamente.) Aquí está el fichero Hello.idl completo.

. Escribir Hello.idl

OMG IDL es un lenguaje puramente declarativo diseñado para especificar interfaces operaciones independientes del lenguaje de programación para aplicaciones distribuidas. OMG especifica un mapeo desde IDL a diferentes lenguajes de programación, incluyendo C, C++. Smalltalk, COBOL, Ada, y Java. Cuando se mapea, cada sentencia del OMG IDL es traducida al la correspondiente sentencia en el lenguaje de programación que hemos elegido. Podemos usar la herramienta idltojava para mapear un interface IDL a Java e implementar las clases cliente. Cuando mapeamos el mismo IDL a C++ e implementamos el servidor en ese lenguaje, el cliene Java y el servidor C++ interoperan a través del ORB como si estuvieran escritos en el mismo lenguaje.

El IDL para Hello world es extremadamente sencillo, su único inteface tiene una sóla aplicación. Necesitamos realizar sólo estos tres pasos.

. Paso 1: Declarar el Módulo CORBA IDL

Un módulo CORBA es un nombre que actúa como contenedor para interfaces y declaraciones relacionados. Corresponde casi con un paquete java. Cada sentencia módulo en un fichero IDL se mapea en una sentencia de paquete Java.

  1. Arrancamos nuestro editor de texto favorito y creamos un fichero llamado Hello.idl.
  2. En nuestro fichero, introducimos la sentencia módulo.
    module HelloApp { 
    	// Add subsequent lines of code here.
    };
    
  3. Grabamos el fichero. Cuando ejecutemos idltojava sobre el IDL, esta sentencia generará una sentencia de paquete en código Java.

. Paso 2: Declarar el Interface

Al igual que los interfaces Java, los interfaces CORBA declaran el contrato API que un objeto tiene con otros objetos. Cada sentencia interface en el IDL se mapea a una sentencia de interface Java.

En nuestro fichero Hello.idl, introduce la sentencia de interface.

module HelloApp {
    interface Hello  // Add
    {                // these
                     // four
    };               // lines.
};

Cuando compilamoe el IDL, esta sentencia generará una sentencia interface en código Java. Nuestras clases cliente y servidor implemetarán el interface Hello de formas diferente.

. Paso 3: Declarar las Operaciones

Las operaciones CORBA son el comportamiento que el servidor promete realizar sobre los clientes que lo invocan. Cada sentencia operación en el IDL genera su corresponiente sentencia método el interface Java generado.

En nuestro fichero Hello.idl, introducimos la sentencia de operación.


module HelloApp {
    interface Hello
    {
        string sayHello();  // Add this line.
    };
};

Cómo nuestra pequeá aplicación Hello World sólo tiene una operación, Hello.idl ya está completo.

. Mapear Hello.idl desde IDL a Java

La herramienta idltojava lee los ficheros OMG IDL y crea los ficheros Java necesarios. La configuración por defecto de idltojava necesita un fichero cliente y servidor (como hicimos para nuestro programa Hello World), simplemente introducimos el nombre de la herramienta y el nombre de nuestro fichero IDL.

  1. Ir al prompt de la línea de comandos.
  2. Cambiar al directorio donde esté nuestro fichero Hello.idl.
  3. Introducimos el comando de compilador.
    idltojava Hello.idl
    

Si listamos los contenidos del directorio, veremos que se ha creado un directorio llamado HelloApp y que contiene cinco ficheros. Intentamos abrir Hello.java en nuestro editor de texto. Se parecerá a esto.

/* Hello.java as generated by idltojava */
package HelloApp;
public interface Hello
    extends org.omg.CORBA.Object {
    String sayHello();
}

Con un interface tan sencillo, es fácil ver cómo las sentencias IDL se mapea para generar las sentencias Java.

Sentencia IDL Sentecia Java
module HelloApp package HelloApp;
interface Hello public interface Hello
string sayHello(); String sayHello();

La única sorpresa es la sentencia extends. Todos los objetos CORBA descienden de org.omg.CORBA.Object para asegurar la funcionalidad necesaria de CORBA. El código necesario lo genera idltojava; no necesitamos hacer el mapeo nosotros mismos.

. Entender la Salida del Compilador idltojava

El compilador idltojava genera un número de ficheros, basándose en las opciones elegidas en la línea de comandos. Como estos proporcionan funcionalidades estándard, podemos ignoralmos hasta el momento de desarrollar y ejecutar nuestro programa. Los cinco ficheros generados por idltojava son.

_HelloImplBase.java
Esta clase abstracta es el esqueleto delservidor, proporcionando funcionalidades básicas de CORBA para el servidor. Implementa el interface Hello.java. La lcase servidor HelloServant desciende de _HelloImplBase.
_HelloStub.java
Esta clase es el cliente, proporciona funcionalidad CORBA al cliente. Implementa el interface Hello.java.
Hello.java
Este interface contiene la versión Java de nuestro interface IDL. Contiene el único método sayHello. El interface Hello.java desciende de org.omg.CORBA.Object, proporcionado también funcionalidades estándares de CORBA.
HelloHelper.java
Esta clase final proporciona funcionalidades auxiliares, notablemente el método narrow requerido para convertir las referencias de los objetos CORBA a sus propios tipos.
HelloHolder.java
Esta clase final conteine un ejemplar público del tipo Hello. Proporciona operaciones para argumentos de entrada y salida, que CORBA tiene pero que no se mapean fácilmente a la semántica Java.

Cuando escribimos nuestro interface IDL, hacemos toda la programación requerida para generar todos estos ficheros para nuestra aplicación distribuida. El único trabajo adicional necesario es la implementación real de las clases cliente y servidor. En la lección siguiente, crearemos las clases HelloClient.java, HelloApplet.java HelloServer.java .

. Resolución de Problemas

Error Message: "idltojava" not found
Si intentamos ejecutar idltojava sobre el fichero Hello.idl y el sistema no puede encontrar idltojava, lo más común es que el ejecutable no esté en el path. Deberemos asegurarnos de que la dirección del idltojava está en nuestro path.
Error Message: preprocessor failed
idltojava usa un preprocesador C/C++ por defecto. Debemos modificar el valor por defecto seleccionando dos variables de entorno, CPP y CPPARGS. Si no queremos usar un preprocesador, podemos desasctivarlo añadiendo -fno-cpp a la línea de comandos de idltojava.

. Desarrollar una Aplicación Cliente

esta lección presenta lo básico para escribir un aplicación cliente CORBA. Aquí está la versión completa de HelloClient.java.

Nota Applet: Durante esta lección nos enfocaremos en escribir una aplicación cliente CORBA, muchos de los pasos son indénticos a los requeridos para escribir applets. La mayor diferencia es que el código del applet aparece en en el método init en vez de en main. Para más información sobre como configurar la página HTML del applet, puedes ver Configurar el Fichero HTML (sólo Applets). Aquí está el código completo para la versión del applet HelloApplet.java.

. Realizar Configuración Básica

El shell bñasico de un cliente CORBA es el mismo que el de muchas aplicaciones Java. Importamos los paquetes necesarios, declaramos la clase de la aplicación, definimos un método main, y recordamos manejar cualquier excepción.

. Importar los Paquetes Requeridos

Arrancamos nuestro editor de texto y grabamos un nuevo fichero llamado HelloClient.java en nuestro directorio de proyecto.

Importar los paqueres requeridos para la clase cliente.

import HelloApp.*;          // The package containing our stubs.
import org.omg.CosNaming.*; // HelloClient will use the naming
			    //	service.
import org.omg.CORBA.*;     // All CORBA applications need these 
			    // classes.

Nota Applets: Si estamos escribiendo un applet, también necesitaremos importar java.awt.Graphics y org.omg.CosNaming.NamingContextPackage.*. Este último paquete contiene excepciones espciales lanzadas por el servicio de nombrado.

. Declarar la Clase Cliente

En HelloClient.java, declara la clase cliente.

public class HelloClient {
    // Add the main method here in the next step.
}

Nota Applets: En la versión applet de este código, HelloApplet.java, declaramos la clase applet de esta forma.

public class HelloApplet extends java.applet.Applet {
    // Put the init() method here in the next step.
}

. Definir un Método main

Cada aplicación Java necesita un método main. Declarado dentro del ambito de la clase HelloClient.

public static void main(String args[]) {
    // Put the try-catch block here in the next step.
}

. manejar Excepciones del Sistema CORBA

Como todos los programas CORBA pueden lanzar excepciones del sistema CORBA en el momento de ejecución, debemos situar toda la funcionalidad del método main dentro de un bloque try-catch. Los programas CORBA lanzan excepciones del sistema siempre que ocurre un problema durante cualquiera de los procesos involucrados en la llamada al servidor desde el cliente.

Nuestro manejador de excepciones sólo imprime el nombre de la excepción y su pila en la salida estándard para que podamos ver qué es lo ha ido mal.

Dentro de main, configuramos un bloque try-catch.

try {
    // Add the rest of the HelloClient code here.
} catch(Exception e) {
    System.out.println("ERROR : " + e);
    e.printStackTrace(System.out);
}

. Crear un Objeto ORB

Un cliente CORBA necesita un objeto ORB local para realizar todas sus ordenes y trabajo IIOP. Cada cliente ejemplariza un objeto org.omg.CORBA.ORB y lo inicializa pasandole al objeto cierta información sobre sí mismo.

Dentro del bloque try-catch de HelloClient.java, declaramos e inicializamos una variable ORB.

ORB orb = ORB.init(args, null);

La llamada al método init del ORB le pasa a nuestra aplicación los argumentos de la línea de ocmandos, permitiendonos seleccioanar propiedaes durante la ejecución.

. Encontrar el Servidor Hello

Una vez que la aplicación tiene un ORB, puede pedirle al ORB que localice el servico real que ncesita, en este caso el servidor Hello. Hay un número de formas para que un cliente CORBA obtenga una referencia inicial a un objeto; nuestra aplicación cliente usará el COS Naming Service especificado por el OMG y proporcionado con Java IDL. Puedes ver Usar Referencias a Objetos Stringified para más información sobre cómo obtenter una referencia inicial a un objeto cuando no hay servicio de nombres disponible.

. Obtener el Contexto de Nombres Inicial

El primer paso para usar el servicio de nombrado es obtener el contecto de nombres inicial. En el bloque try-catch, debajo de la inicialización de uestro ORB, llamamos a orb.resolve_initial_references para obtener un objeto referencia al servidor de nombres.

org.omg.CORBA.Object objRef =
                 orb.resolve_initial_references("NameService");

El string "NameService" está definido para todos los ORBs CORBA. Cuando pasamos este string, el ORB retorna el contexto d enombre inicial, un objeto referencia al servicio de nombres.

. Apuntando hacia el Objeto Referencia

Como con todos los objetos referencia de CORBA, objRef es un objeto CORBA genérico. Para usarlo como un objeto NamingContext, debemos apuntar hacia el tipo apripiado. Añadimos la llamada a narrow justo debajo de la sentencia anterior.

NamingContext ncRef = NamingContextHelper.narrow(objRef);

Aquí vemos el uso de una clase de ayuda genrada por idltojava, similar en funcion a HelloHelper. El objeto ncRef es ahora un org.omg.CosNaming.NamingContext y podmeos usarlo para aceder al servicio de nombres y encontrar otros servicios. Haremos esto en el siguiente paso.

. Encontrar el Servicio de Nombres

Los nombres pueden tener diferentes estructuras dependiendo de la implementación del servicio. Consecuentemente, los servidores de nombres CORBA manejan nombres complejos mediante objetos NameComponent. Cada NameComponent contiene una sola parte, o elemento, del nombre.Un array d eobjeto NameComponent puede contener un path completamente especificado de un objeto en cualquier systema de ficheros o de discos de un ordenador.

Para encontrar el servidor Hello, primero necesitamos un NameComponent que contenfa una cadena identificativa del servidor Hello. Añadimo este código directamente debajo de la llamada a narrow.

NameComponent nc = new NameComponent("Hello", "");

Esta sentencia selecciona el campo id de nc, el nuevo NameComponent, a "Hello" y el campo kind con una cadena vacía.

Como el path del objeto Hello sólo tiene un elemento, creamos un array de un sólo elemento fuera de nc. El método NamingContext.resolve requiere este array para funcionar.

NameComponent path[] = {nc};

Finalmente, pasamos path al método resolve del servicio de nombres, para obtener un objeto referencia al servidor Hello y apuntarlo hacia el objeto Hello.

Hello helloRef = HelloHelper.narrow(ncRef.resolve(path));

Aquí podemos ver la clase HelloHelper funcionando. El método resolve devuelve un objeto CORBA genérico como vimos arriba cuando localizamos el propio servicio de nombres. Por lo tanto, lo apuntamos directamente al objeto Hello, que es el objeto referencia que necesitamos para realizar el resto de nuestro trabajo.

. Invocar a la Operación sayHello

Las invocaciones CORBA se parecen a las llamadas a métodos de un objeto local. Las compilcaciones de ordenar parámetros por el cable, enrutarlos al ORB del lado del servidor, desordenar, y situar la llamada al método servidor son completamente transparentes al programador del cliente. Como casi toda la generación de código está hecha, la invocación es realmente la parte más sencilla de la programación CORBA.

  1. Continuando con el bloque try-catch en HelloClient.java, introducimos la siguiente invocación debajo de la llamada al método resolve del servicio de nombres.
    String hello = helloRef.sayHello();
    
  2. Finalmente, añadimos el código para imprimir los resultados de la invocación en la salida estándard.
    System.out.println(hello);
    
  3. Grabar y cerrar HelloClient.java.

. Configuración del fichero HTML (sólo Applets)

Tutorial.html se utiliza para mostrar nuestro applet finalizado, pero necesitamos personalizar unos pocos atributos y parámetros.

  1. Abrimos Tutorial.html en nuestro editor de texto.
  2. Dentro de la etiqueta APPLET, introducimos el path de nuestro directorio de proyecto como el valor para el atributo CODEBASE.
  3. En la primera etiqueta PARAM, introducimos el nombre de la máquina donde se está ejecutando el servidor de nombres CORBA (la mayoría de las veces será nuestra máquina local) como el valor de ORBInitialHost.
  4. Nos aseguramos de que la segunda etiqueta PARAM contiene el valor de ORBInitialPort que estamos suando para ejecutar el servidor de nombres (está preseleccioanda a 1050 para funcionar con el valor por dfecto suado en los ejemplo de esta sección). En cualquier caso, debería ser un valor por encima de 1028.

Ya estamos listos para escribir el código del servidor.

. Desarrollar el Servidor Hello World

Esta lección presenta lo básico para escribir un servidor CORBA. Aquí está la versión completa de HelloServer.java.

. Realizar la Configuración Básica

La estructura de un programa servidor CORBA es la misma que la mayoría de las aplicaciones Java. Importamos los paquetes necesarios, declaramos la clase servidor, definimos el método main, y recordamos manejar cualquier excepción.

. Importar los Paquetes Necesarios

Arrancamos nuestro editor de texto y grabamos un nuevo fichero llamado HelloServer.java. Luego, importamos los paquetes que necesita la clase cliente.

// The package containing our stubs.
import HelloApp.*;
// HelloServer will use the naming service.
import org.omg.CosNaming.*;
// The package containing special exceptions
// thrown by the name service.
import org.omg.CosNaming.NamingContextPackage.*;
// All CORBA applications need these classes.
import org.omg.CORBA.*;

. Declarar la Clases Servidor

Declaramos la clase servidor.

public class HelloServer {
    // Add the main method here in the next step.
}

. Definir el método main

Declaramos un método main estándard.

public static void main(String args[]) {
    // Add the try-catch block here in the next step.
}

. Manejar las Excepciones del Sistema de CORBA

Como todos los programas CORBA pueden lanzar excepciones del sistema en el momento de la ejecución, situaremos toda la funcionalidad del método main dentro de un bloque try-catch. El manejador de excepciones sólo impleme la excepción y su pila en la slaida estándard para que podamos ver qué tipo de problema a ocurrido.

Dentro de main, configuramos un bloque try-catch.

try {
    // Add the rest of the HelloServer code here.
} catch(Exception e) {
    System.err.println("ERROR: " + e);
    e.printStackTrace(System.out);
}

. Crear un Objeto ORB

Al igual que el cliente, un servidor CORBA necesita un objeto ORB local. Cada servidor ejemplariza un ORB y registra sus objetos sirvientes para que el ORB puede encontrar el servidor cuando recibe las invoaciones para él.

Dentro del bloque try-catch de HelloServer.java, declaramos e inicializamos una variable ORB.

ORB orb = ORB.init(args, null);

La llamada al método init del objeto ORB pasa los argumentos de la línea de comandos del servidor, permitiéndonos configurar ciertas propiedades durante la ejecución.

. Manejar el Objeto Sirviente

Un servidor es un proceso que ejemplariza uno o más objetos sirvientes. El sirviente implementa el interface generado por idltojava y realmente realiza el trabajo de las operaciones sobre el interface. Nuestro HelloServer necesita un HelloServant.

. Ejemplarizar el Objeto Sirviente

Dentro del bloque try-catch, justo debajo de la llamada a init, ejemplarizamos el objeto sirviente.

HelloServant helloRef = new HelloServant();

Esta clase sirviente no está definida todavía; lo harmeos en un paso posterior. Luego conectamos el sirviente al ORB, para que el ORB pueda reconocer las invocaciones sobre él y pasarlas al sirviente correcto.

orb.connect(helloRef);

. Definir la Clase Sirviente

Al final del fichero HelloServer.java, y fuera de la clase HelloServer , definimos la clase para el objeto sirviente.

  1. Declaramos la clase sirviente.
    class HelloServant extends _HelloImplBase {
        // Add the sayHello method here in the next step.
    }
    
  2. La clase sirviente es una subclase de _HelloImplBase por lo que hereda toda la funcionalidad CORBA generada por el compilador.
  3. Declara el método sayHello.
    public String sayHello() {
        // Add the method implementation here in the next step.
    }
    
  4. Escribir la implementación del método sayHello.
    return "\nHello World!!\n";
    

. Trabajar con el Nombrado COS

El HelloServer funciona con el servicio de nombrado para hacer que las operaciones del objeto sirviente estén disponibles para los clientes. El servidor necesita un objeto referencia hacia el nombre del sevicio, para que pueda registrarse a sí mismo y asegurarse de que las llamadas al interface Hello se enrutan hacia su objeto sirviente.

. Obtener el Contexto de Nombrado Inicial

En el bloque try-catch, debajo de la ejemplarización del sirviente, llamamos a orb.resolve_initial_references para obtener un objeto referencia hacia el nombre del servidor.

org.omg.CORBA.Object objRef =
    orb.resolve_initial_references("NameService");

El string NameService está dfinido para todos los ORBs de CORBA. Cuando pasamos este string, el ORB retorna un objeto de contexto de nombrado que es un objeto referencia para el nombre del servicio.

. Apuntar el Objeto Referencia

Al igual que los objetos referencia CORBA, objRef es un objeto CORBA genérico. Para usarlo como un objeto NamingContext, debemos aputarle hacia su propio tipo. Añadimos la llamada a narrow justo debajo de la sentencia anterior.

NamingContext ncRef = NamingContextHelper.narrow(objRef);

Aquí podmeos ver el uso de una clase ayuda generada por idltojava, similar en función a HelloHelper. El objeto ncRef es ahora un org.omg.CosNaming.NamingContext y podemos usarlo para acceder al servicio de nombrado y registrar el servidor.

. Registrar el Sirviente con el Nombre del Servidor

  1. Debajo de la llamada a narrow, creamos un nuevo miembro NameComponent.
    NameComponent nc = new NameComponent("Hello", "");
    
  2. Esta sentencia sonfigura el campo id de nc, del nuevo NameComponent, a "Hello" y el componten kind a un string vacío. Como el path de Hello tiene un sólo elemento, creamos el array de un elemento que NamingContext.resolve necesita para su trabajo.
    NameComponent path[] = {nc};
    
  3. Finalmente, pasamos el path y el objeto sirviente al servicio de nombrado, ocultando el objeto sirviente la identidad de "Hello".
    ncRef.rebind(path, helloRef);
    

Ahora, cuando el cliente llame a resolve("Hello") sobre el contexto de nombrado inicial, el servicio de nombrado devolverá un objeto referencia hacia el sirviente Hello .

. Esperar Llamadas

El servidor está listo; sólo necesita esperar peticiones de los clientes. Para consegui esto, introducimos el siguiente código al final (pero dentro) del bloque try-catch.

java.lang.Object sync = new java.lang.Object();
synchronized(sync) {
    sync.wait();
}

Esta forma de Object.wait requiere que HelloServer permanezca vivo (aunque incosciente) hasta que vengan las llamadas desde el ORB. Como está dentro de main, después de que se complete una llamada y sayHello retorne, el servidor espera de nuevo.

. Compilar y Ejecutar la Aplicación Hello World

Esta sección muestra cómo compilar y ejecutar los programas servidor y cliente, que juntos forman la aplicación "Hello World".

. Compilar la Aplicación Cliente

  1. Compilamos HelloClient.java.
    javac HelloClient.java HelloApp\*.java
    
  2. Corregimos cualquier error de nuestro fichero y recompilamos si es necesario.
  3. Veremos el fichero HelloClient.class en el directorio del proyecto.

. Compilar el Servidor

  1. Compilar HelloServer.java.
    javac HelloServer.java HelloApp\*.java
    
  2. Corregimos cualquier error de nuestro fichero y recompilamos si es necesario.
  3. Deberiamos ver los ficheros HelloServer.class y HelloServant.class .

. Ejecutar la aplicación Cliente-Servidor

  1. Desde el Prompt de MD-DOS (en Widnows) o el shell de comandos (en UNIX) arrancamos el servidor de nombres de Java IDL.
    tnameserv -ORBInitialPort nameserverport 
    

    Observa que nameserverport es el puerto en el que queremos que funcione el servidor. So no lo especificamos, se elegirá por defecto el puerto 900. También nota, si usas software Solaris, que deberias empezar a arrancar proceso en un puerto inferior al 1024. Por esta razón, recomendamos que uses un puerto mayor o igual a 1024.

  2. Desde un segundo prompt o shell, arrancamos el servidor Hello.
    java HelloServer -ORBInitialHost nameserverhost
         -ORBInitialPort nameserverport
    

    Observa que nameserverhost es el nombre del host en el que se está ejecutando el servidor de nombres IDL. Podemos omitir -ORBInitialHost nameserverhost si el servidor de nombres se está ejecutando en el mismo host que el servidor Hello. Podemos dejar en blanco -ORBInitialPort nameserverport si el servidor de nombres se está ejecutando en el puerto por defecto.

  3. Desde un tercer prompt del shell, ejecutamos la aplicación cliente Hello.
    java HelloClient -ORBInitialHost nameserverhost 
         -ORBInitialPort nameserverport
    

    Observa que nameserverhost es el nombre del host en el que se está ejecutando el servidor de nombres IDL. Podemos omitir -ORBInitialHost nameserverhost si el servidor de nombres se está ejecutando en el mismo host que el servidor Hello. Podemos dejar en blanco -ORBInitialPort nameserverport si el servidor de nombres se está ejecutando en el puerto por defecto.

  4. El cliente imprime el string del servidor en la línea de comandos.
    Hello world!!
    

Debemos acordarnos de parar los procesos tnameserv y HelloServer despúes de que el cliente retorne satisfactoriamente.

. Resolución de Problemas

Specifying ORB Initial Port
El puerto inicial por defecto del ORB es el 900. Si lo prefieres, puedes omitir la especificación del puerto si arrancas el servidor de nombres en el puerto 900. Si usas software Solaris, debes comenzar a arrancar proceso por debajo del puerto 1024. Recuerda salir del acceso raíz antes de continuar con el tutor si has elegido este puerto para tu servidor de nombres.
Class Definition Not Found Error
Si el compilador Java (javac) lanza un NoClassDefFoundError, intenta usar la opción -cp (classpath) en la línea de comandos cuando compiles los ficheros fuente.
javac -cp . *.java HelloApp\*.java

. Usar Objetos Referencia Stringified

Para invocar una operación sobre un objeto CORBA, una aplicación cliente necesita una referencia al objeto. Podemos obtener dicha referencia de una de estas formas, llamando a ORB.resolve_initial_references o suando otro objeto CORBA (como el servicio de nombres). En las lecciones anteriores, usamos ambos métodos para obtener un objeto referencia inicial.

Sin embargo, frecuentemente no hay un serivicio de nombres disponible en el entorno distibuido. En esta situación, los clientes CORBA usan un objeto referencia stringified (encadenada) para encontrar su primer objeto.

En esta lección, aprenderemos cómo crear un objeto referencia stringified como parte de la configuración del servidor, y cómo el cliente obtiene esta referencia y la (desencadena) para usarla como un objeto referencia real. Puedes encontrar la versión completa del código fuente en HelloStringifiedServer.java y en HelloStringifiedClient.java.

. Crear un Objeto Referencia Stringified

Para que el cliente tenga disponible un objeto referencia stringified, el servidor debe crear la referencia y almacenarla en algún lugar al que tenga acceso el cliente. Nuestra referencia se escribirá en el disco como un fichero de texto.

  1. Compiamos nuestro fichero existente HelloServer.java.
  2. Como el nuevo servidor escribirá un fichero en el disco, necesitamos añadir una sentencia import.
    // needed for output to the file system.
    import java.io.*;
    
  3. El nuevo servidor no usará el servicio de nombres, por lo que no necesitaremos los paquetes CosNaming . Borramos estas líneas del código
    // not needed for stringified version
    // remove from code
    import org.omg.CosNaming.*;
    import org.omg.CosNaming.NamingContextPackage.*;
    
  4. Borramos el código que obtiene el contexto de nombrado inicial y resuelve la referencia al objeto Hello.
    // Get the root naming context
    org.omg.CORBA.Object objRef =
        orb.resolve_initial_references("NameService");
    NamingContext ncRef = NamingContextHelper.narrow(objRef);
    
    // Bind the object reference in naming
    NameComponent nc = new NameComponent("Hello", "");
    NameComponent path[] = {nc};
    ncRef.rebind(path, helloRef);
    
  5. Llamamos al método object_to_string del ORB y le pasamos la referencia al objeto sirviente. Esto devuelve el objeto referencia en un string que puede sar grabado en un fichero de disco.
     String ior = orb.object_to_string(helloRef);
    
  6. Construimos el path al fichero que vamos a almcenar, usando las propiedades del sistema para determinar la estructura y la síntaxis del path.
    String filename = System.getProperty("user.home") +
        System.getProperty("file.separator")+"HelloIOR";
    
  7. Usamos las operaciones estándars de Java para escribir el stringified ior en el disco.
    FileOutputStream fos = new FileOutputStream(filename);
    PrintStream ps = new PrintStream(fos);
    ps.print(ior);
    ps.close();
    

Cuando se ejecuta HelloStringifiedServer, en vez de llamar al ORB y registrar el objeto sirviente con el nombre, crea el fichero de texto HelloIOR que contiene una referencia stringified al sirviente. El fichero está almacenado en nuestro directorio home.

. Obtener un Objeto Referencia Stringified

  1. copiamos nuestro fichero existente HelloStringifiedClient.java.
  2. Como el nuevo vliente leerá un fichero desde el disco, necesimatos cambiar las sentencias import.
    // needed for input from the file system.
    import java.io.*;
    
  3. El nuevo cliente no usará el servicio de nombres, por lo que no necesitaremos el paquete CosNaming. Borramos está línea del código.
    // not needed for stringified version
    import org.omg.CosNaming.*;
    
  4. Borramos el código que obtiene el contexto de nombrado inicial y registra el sirviente con el servicio de nombres.
    // Get the root naming context
    org.omg.CORBA.Object objRef =
        orb.resolve_initial_references("NameService");
    NamingContext ncRef = NamingContextHelper.narrow(objRef);
    
    // Resolve the object reference in naming
    NameComponent nc = new NameComponent("Hello", "");
    NameComponent path[] = {nc};
    
    Hello helloRef = HelloHelper.narrow(ncRef.resolve(path));
    
  5. Usamos las operaciones estándards de Java para leer el fichero que tiene el objero referencia. Observamos que los programas cliente y servidor deben conocer el nombre del fichero y donde está almacenado.
    String filename = System.getProperty("user.home") + 
            System.getProperty("file.separator") + "HelloIOR";
    FileInputStream fis = new FileInputStream(filename);
    DataInputStream dis = new DataInputStream(fis);
    String ior = dis.readLine();
    
  6. La aplicación HelloStringifiedClient ahora tiene un objeto String que contiene el objeto referencia stringified.

. Convertir el Objeto Referencia

Para convertir el objeto referencia en ior, llamamos al método estándard del ORB.

org.omg.CORBA.Object obj = orb.string_to_object(ior);

Finalmente, apuntamos el objeto CORBA hacia su propio tipo, para que el cliente pueda invocarlo.

Hello helloRef = HelloHelper.narrow(obj);

El resto del código del cliente permanece igual.

. Compiliar un Hello World con Stringified

Para compilar Hello World.

  1. Compilamos el código fuente.
    javac *.java
    
  2. Corregimos cualquier error que hubiera en los ficheros y compilamos si fuera necesario.
  3. Deberiamos ver HelloStringifiedServer.class, HelloServant.class, y HelloStringifiedClient.class en nuestro directorio.

. Ejecutar un Hello World con Stringified

Para asegurarnos que estamos ejecutando nuestro propio servidor, chequeamos que todos lo procesos del servidor Hello y del servicio de nombres se han parado. Y los paramos si están en ejecución.

  1. Arrancamos el servidor Hello.
    java HelloStringifiedServer -ORBInitialPort 1050
    
  2. Ejecutamos la aplicación Hello desde otra ventana.
    java HelloStringifiedClient -ORBInitialPort 1050
    
  3. El cliente imprime el string desde el servidor a la línea de comandos.
    Hello world!!
    

Recuerda parar el proceso HelloStringifiedServer después de que la aplicación cliente retorne de forma satisfactoria.

 
Patrocinados
 

Copyright © 1999-2007 Programación en castellano. Todos los derechos reservados.
Formulario de Contacto - Datos legales - Publicidad
Mantenida por: Claudio y Dani.

Hospedaje web y servidores dedicados linux por Ferca Network

red internet: jugar gratis | amor | navidad 2009 | registro de dominios | servidores dedicados
más internet: comprar | gratis | posicionamiento en buscadores | decoración libre | gifs animados