Documentos de Académico
Documentos de Profesional
Documentos de Cultura
CORBACon Java IDL
CORBACon Java IDL
NamingContext ServNombres =
NamingContextHelper.narrow(
Orb.resolve_initial_references("NameService"));
Teniendo disponible una reIerencia al servicio de nombres es posible realizar basicamente dos tareas
diIerentes: registrar un objeto, Iacilitando un camino y una reIerencia, o bien resolver una reIerencia
partiendo del camino. En el primer caso se usa el metodo rebind(), Iacilitando el camino que
identiIicara al objeto y una reIerencia, mientras que en el segundo nos serviremos del metodo
resolve() entregando como unico parametro el citado camino.
Implementacin del servidor
Del servidor hasta ahora tan solo contamos con un esqueleto, la clase _IConsultaImplBase, que
servira como base de la clase en la que se implementen los metodos inicialmente establecidos en la
interIaz IDL. Aunque en este caso tan solo tenemos una, en la practica existira una clase de
implementacion por cada interIaz que se haya deIinido. Esto no conlleva, sin embargo, que tengan que
existir varios servidores de objetos, ya que un mismo servidor puede preparar y registrar todos los objetos
que sean precisos.
El modulo ServidorConsulta.java, que puede ver en el Listado 5, contiene la deIinicion de dos
clases: ConsultaServant y ServidorConsulta. La primera deriva de _IConsultaImplBase
y es la clase que realmente implementa la Iuncionalidad de la interIaz IConsulta, en este caso mostrar
los parametros recibidos y devolver una cadena indicando que la consulta se ha ejecutado. En la practica
esta clase podria realizar cualquier Iuncion, logicamente mas util que la mostrada en este ejemplo.
La segunda clase es realmente la aplicacion que actua como servidor, tal y como denota la existencia
del metodo main(). En este se comienza inicializando el ORB, creando un objeto de la clase
ConsultaServant y conectando dicho objeto con el ORB, de tal Iorma que este pueda resolver
adecuadamente las peticiones. En este momento tenemos un objeto CORBA preparado para ser usado.
Para que el objeto anterior pueda estar accesible desde un cliente, ya sea en la misma maquina o en
cualquier otra conectada a la red, es necesario inIormar al servicio de nombres de cual es el nombre y la
reIerencia. Tras obtener una reIerencia al servicio de nombres preparamos el camino con que se
identiIicara el objeto, en este caso el nombre IConsulta, y usamos el metodo rebind() para realizar
el registro.
// Este mdulo contiene el servidor, con el correspondiente
// mtodo main(), y la clase que servir a las peticiones
// de los clientes CORBA
import SvrConsultas.*; // Importamos el esqueleto y clases auxiliares
// Paquetes para acceder al ORB y al servicio de nombres
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
// Esta clase implementa la interfaz IConsulta derivando del
// esqueleto generado por idltojava
class ConsultaServant extends _IConsultaImplBase {
// simplemente implementamos el mtodo
public String Consulta(String Parametros) {
// que se limitar a mostrar los parmetros recibidos
System.out.println(Parametros);
// y devolver una cadena como resultado
return "Ejecutada la consulta\n" + Parametros;
}
}
// Esta clase es el servidor propiamente dicho
public class ServidorConsulta {
// El mtodo main() es el punto de entrada al servidor
public static void main(String args[]) {
try {
// Obtenemos una referencia al ORB, inicializndolo
ORB Orb = ORB.init(args, null);
// Creamos el objeto que implementa la interfaz IConsulta
ConsultaServant Servidor = new ConsultaServant();
// Conectamos el objeto CORBA con el ORB
Orb.connect(Servidor);
// Obtenemos una referencia al servicio de nombres
NamingContext ServNombres = NamingContextHelper.narrow(
Orb.resolve_initial_references("NameService"));
// Preparamos el camino con el nombre del objeto
NameComponent NombreInterfaz =
new NameComponent("IConsulta", "");
NameComponent CaminoObjeto[] = {NombreInterfaz};
// y lo registramos en el espacio de nombres
// facilitando el camino y la referencia al objeto
ServNombres.rebind(CaminoObjeto, Servidor);
System.out.println(
"Servidor esperando solicitudes de consultas");
// Esperamos a recibir peticiones de clientes
java.lang.Object RS = new java.lang.Object();
synchronized(RS) {
RS.wait();
}
} catch (Exception X) { // en caso de fallo
System.err.println(X); // mostrar toda la informacin
X.printStackTrace(System.out); // disponible
}
}
}
Listado 5. Implementacin del servidor ServidorConsulta
Si la aplicacion servidor, que es la que ha creado el objeto que Iinalmente atendera a las solicitudes de
los clientes, termina sin mas, dicho objeto sera destruido y el servicio de nombres contara con una
reIerencia a algo inexistente. Por eso es preciso esperar indeIinidamente solicitudes de clientes.
Observe que toda la operacion de inicializacion del ORB, conexion y registro en el servicio de
nombres se protege en un bloque contra posibles excepciones. La mas habitual es que no pueda accederse
al servicio de nombres, bien porque no se haya iniciado o se encuentre escuchando en otro servidor o
puerto.
Codificacin de un cliente
Asumiendo que ya hemos creado nuestro servidor, estamos en disposicion de crear el cliente o clientes
que utilizaran sus servicios. En el Listado 6 se muestra una simple aplicacion que usa el primer parametro
Iacilitado en la linea de comandos para realizar una consulta, mostrando en pantalla el resultado obtenido
y Iinalizando.
Los primeros pasos dados en el metodo main() del cliente son similares a los anteriormente
descritos en el servidor: se inicializa el ORB, se obtiene una reIerencia al servicio de nombres y se
// Este es el programa cliente, que obtendr una referencia
// al objeto sirvindose del servicio de nombres, tras lo
// cual ejecutar la consulta que se haya introducido como
// parmetro de entrada
import SvrConsultas.*; // Importamos el stub y las clases auxiliares
// Paquetes para acceder al ORB y al servicio de nombres
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
public class Cliente {
// Punto de entrada al cliente
public static void main(String args[]) {
try {
// Inicializamos el ORB y obtenemos la referencia
ORB Orb = ORB.init(args, null);
// Obtenemos una referencia al servicio de nombres
NamingContext ServNombres = NamingContextHelper.narrow(
Orb.resolve_initial_references("NameService"));
// Preparamos el camino con el nombre del objeto
NameComponent NombreInterfaz =
new NameComponent("IConsulta", "");
NameComponent CaminoObjeto[] = {NombreInterfaz};
// Solicitamos al servicio de nombres la resolucin
// de la referencia
IConsulta RefServ = IConsultaHelper.narrow(
ServNombres.resolve(CaminoObjeto));
// y la usamos para ejecutar la consulta
String Resultado = RefServ.Consulta(args[0]);
System.out.println(Resultado); // y mostrarla
} catch (Exception X) { // si hay algn fallo
System.out.println(X); // mostrar toda la informacin
X.printStackTrace(System.out); // disponible
}
}
}
Listado 6. Implementacin del cliente
prepara el camino con el nombre del objeto al que quiere accederse. Observe que no se usa el metodo
connect() del ORB, puesto que el cliente no dispone de un objeto que pondra a disposicion de otros
programas.
Usando el metodo resolve() del servicio de nombres se obtiene una reIerencia al objeto servidor,
siempre asumiendo que dicho servidor este en Iuncionamiento y sea posible acceder a el mediante el
citado servicio de nombres. La reIerencia devuelta es generica, por lo que es preciso realizar una
conversion usando el metodo narrow() de la clase auxiliar IConsultaHelper generada
previamente por idltojava.
Llegados a este punto ya tenemos la reIerencia a la interIaz IConsulta, sin importar el punto en el
que realmente se esta ejecutando el objeto servidor. Aparentemente el objeto se ejecuta de Iorma local,
por lo que no tenemos mas que llamar al metodo Consulta() entregando los parametros de la consulta
y obteniendo el correspondiente resultado, que mostramos seguidamente en la salida estandar. Dados
estos pasos el programa termina y se devuelve a la linea de comandos.
Al igual que ocurre con el servidor, la mayor parte del codigo del cliente se encuentra en el interior de
un bloque try que nos permite interceptar cualquier excepcion que pueda producirse. En este caso
simplemente se da salida a toda la inIormacion disponible. En un cliente real seria mas apropiado
controlar excepciones concretas inIormando al usuario de la imposibilidad de acceder al servicio de
nombres, la inexistencia del objeto que se solicita, etc.
Concluyendo
Como ha podido verse en este articulo, crear servidores y clientes CORBA no es una tarea compleja
usando Java IDL, una de las novedades mas interesantes de la plataIorma Java 2. En principio, sobre todo
si solo es usuario del lenguaje Java, puede no apreciar ninguna ventaja de CORBA respecto a Java RMI,
mecanismo este ultimo que permite la misma Iuncionalidad.
Las ventajas de Java IDL, sin embargo, son muchas. Seguramente la mas importante es la
interoperabilidad con cualquier cliente o servidor CORBA, indistintamente del sistema en que este
Iuncionando y el lenguaje en que se haya desarrollado. Siempre que los objetos esten usando un ORB
compatible con la especiIicacion CORBA 2.0 y se apoyen en IIOP como protocolo de comunicacion, no
existira problema alguno en ello.
Es posible, por ejemplo, crear un cliente ligero en Java para usar servicios CORBA creados en
COBOL en sistemas . De esta Iorma dichos servicios estarian accesibles desde cualquier
cliente de red a traves de un navegador web, aplicaciones a la que estan acostumbrados la mayoria de los
usuarios. Es simplemente un ejemplo de como renovar y mejorar un sistema sin necesidad de descartar el
codigo ya existente, algo que si habria que hacer con Java RMI puesto que servidor y clientes deberian
estar escritos en Java.