Programación en castellano Añadir una dirección | Buscador | Cursos | Artículos | Foros | Formación

Sistema de Nombrado en Java (JNDI) [Parte I]
Autor: Sun
Traductor: Juan Antonio Palos (Ozito)


En esta página:


Carga de Clases

El JNDI es un API definido independientemente de cualquier implementación de nombrado específico o servico de directorio. Para que una aplicación, un applet, o una unidad de programa puedan usar JNDI, deben especificar el proveedor de servicios a usar y deben tener acceso a los ficheros class del proveedor. Un sólo programa podría usar más de un proveedor. Además, el programa y/o los proveedores podrían usar facotrías de objetos, factorías de clases, y factorías de control, cuyos ficheros class también deben estar disponibles para el JNDI. Además, el JNDI necesita acceder a los ficheros de recursos de aplicación (ver la sección Ficheros de Recursos de Aplicación) proporcionados por el programa, los proveedores y otros componentes. En todos estos casos, el JNDI necesita cargar clases y ficheros de recursos. Esta sección explica cómo el JNDI usa los cargadores de clases y cómo nos puede afectar su utilización.

Cargadores de Clases en Segundo Plano

La carga de clases significa que las clases Java y los recursos se cargan dentro del JRE (Java Runtime Environment). Controla un rango de distintas políticas como desde dónde cargar las definiciones de clases hasta el formato de los datos de las definiciones de clases.

En versiones anteriores del JDK 1.1, no existía relación entre distintos cargadores de clases, Un cargador de clases del sistema es responable de cagar en el JRE, la aplicación y las clases y recursos en el classpath de la aplicación. Un cargador de clases de applet es resposnable de cargar los applets y sus recursos relacionados, posiblemente a través de la red comunicándose con un servidor Web.

En la Java 2 Platform, Standard Edition, v1.2 y versiones posteriores, los cargadores de clases tienen una relación jerárquica. Cada cargador de clase tiene un cargador de clases padre. Cuando se le pide a un cargador de clases que cargue una clase o un recurso, consulta con su cargador de clases padre antes de intentar cargar el ítem el mismo. El padre, a su vez consulta a su padre, etc. Por esto es sólo si después de todos los cargadores de clases ancestros no pueden encontrar el ítem que el cargador de clases actual obtiene.

Un cargador de clases bootstrap es el responsable de cargar el JRE. Es la "ráiz" del árbol de cargadores de clases. El cargador de clases del sistema es un descendiente del cargador de clases bootstrap.

Es el responsable de cargar la aplicación, así como las clases y recursos en el classpath de la aplicación.

La plataforma Java 2 también presenta la noción de cargador de clases de contexto. Un cargador de clases de contexto de threads esta, por defecto, configurado como el cargador de clases de contexto de los padres del thread. La jerarquía de threads esta enraizada en el thread primordial (el que ejecuta el programa). El cargador de clases de contexto del thread primordial es configurado como el cargador de clases que cargó la aplicación. Por eso amenos que cambiemos explícitamente el cargador de clases de contexto del thread, su cargador de clases de contexto será el mismo que el de la aplicación. Es decir, el cargador de clases de contexto puede cargar las clases que pueda cargar la aplicación. Este cargador lo usa el JRE como el RMI (Java Remote Method Invocation) para cargar clases y recursos en beneficio del usuario de la aplicación. El cargador de clases de contexto, como el cargador de la plataforma Java 2, tiene un cargador de clases padre y soporta el mismo modelo de delegación para la carga de clases descrito anteriormente.

Cargar Clases con el Software JDK 1.1

Cuando usamos el JNDI con el JDK 1.1, debemos situar los ficheros JARs del proveedor de servicios y los ficheros JARs o los ficheros class que contienen las factorías en el classpath de la aplicación. Si estamos usando un applet, debemos situar dichos ficheros en el directorio codebase del applet y/o en las localizaciones de los archivos. Consecuentemente, el cargador de clases que carga los JARs del JNDI normalmente es el mismo que carga la aplicación y las factorías.

Observa que no podemos usar los ficheros de recursos de apliación JNDI con el JDK 1.1. Puedes ver la sección Ficheros de Recurso de Aplicación para más detalles.

Cargar Clases en la Plataforma Java 2

Cuando usamos el JNDI con la plataforma Java 2, el cargador de clases que carga las clases JNDI normalmente es diferente del que carga la aplicación, Por ejemplo, en el Java 2 SDK, v1.3, las clases JNDI las carga el cargador de clases bootstrap mientras que las clases de la aplicación las carga el cargador de clases del sistema. En el Java 2 SDK, v1.2, si instalamos el JNDI como una extensión instalada, las clases JNDI las carga el cargador de clases responsable de cargar las extensiones instaladas, mientras que las clases de la aplicación las carga el cargador de clases del sistema. Como resultado, si el JNDI usa su cargador de clases para cargar los proveedores de servicio y las factorías, podría no ver las mismas clases que la aplicación. Por lo tanto, para intentar ver lo mismo que la aplicación puede ver, el JNDI usa el cargador de clases de contexto del thread llamante cuando está cargando las clases para los proveedores de servicios, las factorías y los ficheros de recursos de aplicación.

En raras circunstancias, querremos cambiar el cargador de clases del contexto del thread para que afecte al modo de encontrar las clases JNDI. Esto podría ocurrir, por ejemplo, cuando el entorno en el que estamos trabajando no ve apropiadamente el cargador de clases de contexto. Por ejemplo, un bug en el Java 2 SDK, Standard Edition, v1.2.2 hace que el AWT (Abstract Window Toolkit) no configure los oyentes del cargador de clases de contexto del thread para qu sea el cargador de clases que carga el applet. Consecuentemente, lo métodos de retrollamada invocados por los threads oyentes no tienen acceso al proveedor de servicios ni a las factorías que el applet por otro lado puede cargar explícitamente. O, podríamos querer añadir un repositorio adicional de fichero JAR o class que contenga proveedores o factorías especiales para nuestras aplicaciones o applets. Para cambiar el cargador de clases de contexto del thread, usamos Thread.setContextClassLoader().

Aquí tenemos un ejemplo.

ClassLoader prevCl = Thread.currentThread().getContextClassLoader();

// Create the class loader by using the given URL
// Use prevCl as parent to maintain current visibility
ClassLoader urlCl = 
    URLClassLoader.newInstance(new URL[]{new URL(url)}, prevCl);

try {
    // Save the class loader so that you can restore it later
    Thread.currentThread().setContextClassLoader(urlCl);

    // Expect that the environment properties are in the
    // application resource file found at "url"
    Context ctx = new InitialContext();

    System.out.println(ctx.lookup("tutorial/report.txt"));

    // Do something useful with ctx
    ...
} catch (NamingException e) {
    // Handle the exception
} finally {
    // Restore
    Thread.currentThread().setContextClassLoader(prevCl);
}

Este ejemplo crea un URLClassLoader que carga clases desde una URL específicada. Luego crea un contexto inicial y realiza otras operacioens JNDI dentro del contexto de ese cargador de clases. En este ejemplo, el cargador de clases sólo afecta al modo de inicialización del contexto inicial (mediante un fichero de recursos de aplicación encontrado por el nuevo cargador de clases), así como en el resultado de lookup() (mediante la factoría de objetos nombrada en el fichero de recursos de aplicación y el fichero class de la factoría encontrado por el nuevo cargador de clases. Para ejecutar este programa, debemos suministrar la URL codebase de esta forma.

# java ChangeClassLoader file:/some/directory/somewhere/

En este codebase, podemos especificar un fichero jndi.properties.

En este ejemplo particular, este es el fichero jndi.properties en el directorio del codebase.

java.naming.factory.initial=com.sun.jndi.fscontext.FSContextFactory
java.naming.provider.url=file:/tmp
java.naming.factory.object=FooObjectFactory

En el mismo directorio codebase está la definición de la clase para FooObjectFactory, que cuando se el da un objeto java.io.File siempre devuelve el string "foo". Cuando ejecutamos este programa, veremos esta salida.

foo

Si no vemos esta salida, debemos chequear la corrección del argumento URL.

Debemos recordar que si estamos nombrando un directorio codebase, debemos incluir una barra inclinada al final de la URL.

Cargar Clases desde Localizaciones Pre-Especificadas

En algunos casos, la localización de los ficheros class se especifica explícitamente. Por ejemplo, podemos especificar el codebase para una factoría de objetos en su Reference.

Cuando el JNDI lea dicho objeto desde el servicio de nombres o de directorio, usará un cargador de clases para el codebase nombrado en la Reference para obtener los ficheros class de la factoría. El padre de este cargador de clases es el cargador de clases de contexto del thread.


Principio Página
© 1999-2002, Programación en castellano, s.l.
Contacto - Datos legales

ReD Internet: Hospedaje Web | envio sms gratis | Salvapantallas | Fondos de Escritorio, famosas | melodias moviles gratis| Gratis