Descripción general de JNDI, Parte 1: Introducción a los servicios de nombres

Aquellos de ustedes que han estado en una biblioteca y aún pueden recordar la experiencia pueden recordar el proceso de encontrar un libro de la biblioteca. Si no está en contacto con su lado anticuario, esta situación le parecerá desconocida; pero de vez en cuando me dirijo a una biblioteca local para buscar un libro genuino sin conexión. Las bibliotecas están llenas de miles de cosas: están polvorientas y están hechas de pulpa de madera y piel de vaca, pero son fascinantes a su manera. En cualquier caso, cuando surge la compulsión de encontrar una determinada, evito el curso ingenuo de caminar arriba y abajo por los pasillos de la biblioteca buscándola y me dirijo en su lugar al catálogo de fichas.

TEXTBOX: TEXTBOX_HEAD: Descripción general de JNDI: ¡Lea la serie completa!

  • Parte 1. Introducción a los servicios de nombres
  • Parte 2. Utilice los servicios de directorio JNDI para administrar mejor sus aplicaciones distribuidas

  • Parte 3. Utilice JNDI para almacenar los objetos de su aplicación distribuida

  • Parte 4. Reúna lo que ha aprendido con una aplicación habilitada para JNDI: END_TEXTBOX

Un catálogo de tarjetas, para los no iniciados, asigna los nombres de los libros a su ubicación en la biblioteca. Al ir primero al catálogo de tarjetas y buscar la ubicación del libro, me ahorro una cantidad significativa de caminar. (Por cierto, he oído que algunas bibliotecas de hecho permiten a los usuarios usar computadoras en lugar del catálogo de tarjetas. Lo tienen a la mitad, ahora, si simplemente ponen la información de los libros en la computadora a la que pertenece. ..)

Por sorprendente que parezca, la noción de catálogo de tarjetas también es bastante útil en el mundo de la informática. En informática, lo llamamos servicio de nombres, que asocia los nombres con las ubicaciones de los servicios y con la información. Proporciona a los programas informáticos una única ubicación donde pueden encontrar los recursos que necesitan. Por cierto, los programas no pierden el tiempo realizando el equivalente electrónico de caminar por los pasillos y tampoco requieren que las ubicaciones estén codificadas en su lógica.

Encontrar recursos es de particular importancia en entornos empresariales a gran escala, donde las aplicaciones que crea pueden depender de los servicios proporcionados por aplicaciones escritas por otros grupos en otros departamentos. Una infraestructura de nombres bien diseñada hace posible este tipo de proyectos, y la falta de uno los hace imposibles. De hecho, muchos esfuerzos de reingeniería de procesos comerciales comienzan con el diseño y la implementación de una infraestructura de directorio y nombres sólida para toda la empresa.

Este mes, presento la Interfaz de directorio y nombres de Java (JNDI). JNDI proporciona una interfaz de denominador común para muchos servicios de nombres existentes. Como tal, JNDI no fue diseñado para reemplazar la tecnología existente; en cambio, proporciona una interfaz común a los servicios de nombres existentes. Comencemos por echar un vistazo a algunos de estos servicios.

Introducción a los servicios de nombres

La siguiente figura muestra la organización de un servicio de nombres genérico.

Un servicio de nombres mantiene un conjunto de enlaces. Los enlaces relacionan los nombres con los objetos. Todos los objetos en un sistema de nomenclatura se nombran de la misma manera (es decir, se suscriben a la misma convención de nomenclatura ). Los clientes utilizan el servicio de nombres para localizar objetos por su nombre.

Hay varios servicios de nombres existentes, algunos de los cuales describiré a continuación. Cada uno sigue el patrón anterior, pero difieren en los detalles.

  • Naming COS (Common Object Services): el servicio de nombres para aplicaciones CORBA; permite que las aplicaciones almacenen y accedan referencias a objetos CORBA.

  • DNS (sistema de nombres de dominio): el servicio de nombres de Internet; mapea nombres fáciles de usar (como www.etcee.com) en direcciones IP (Protocolo de Internet) compatibles con computadoras en notación de cuatro puntos (207.69.175.36). Curiosamente, DNS es un servicio de nombres distribuido , lo que significa que el servicio y su base de datos subyacente se distribuyen en muchos hosts en Internet.

  • LDAP (Protocolo ligero de acceso a directorios): desarrollado por la Universidad de Michigan; como su nombre lo indica, es una versión ligera de DAP (Directory Access Protocol), que a su vez forma parte de X.500, un estándar para servicios de directorio de red. Actualmente, más de 40 empresas respaldan LDAP.

  • NIS (Network Information System) y NIS +: servicios de nombres de redes desarrollados por Sun Microsystems. Ambos permiten a los usuarios acceder a archivos y aplicaciones en cualquier host con una única identificación y contraseña.

Características comunes

Como mencioné anteriormente, la función principal de un sistema de nombres es vincular nombres a objetos (o, en algunos casos, a referencias a objetos, más sobre esto en un momento). Para ser un servicio de nombres, un servicio debe, como mínimo, proporcionar la capacidad de vincular nombres a objetos y buscar objetos por nombre.

Muchos sistemas de nombres no almacenan objetos directamente. En cambio, almacenan referencias a objetos. Como ilustración, considere DNS. La dirección 207.69.175.36 es una referencia a la ubicación de una computadora en Internet, no a la computadora en sí.

JNDI proporciona una interfaz que admite todas estas funciones comunes. Presentaré esta interfaz más adelante en este artículo.

Sus diferencias

También es importante comprender en qué se diferencian los servicios de nombres existentes, ya que JNDI debe proporcionar una abstracción viable que evite esas diferencias.

Aparte de las diferencias funcionales, la diferencia más notable es la forma en que cada servicio de nombres requiere que se especifiquen los nombres: su convención de nombres. Algunos ejemplos deberían ilustrar el problema.

En DNS, los nombres se crean a partir de componentes separados por puntos ("."). Leen de derecha a izquierda. El nombre "www.etcee.com" nombra una máquina llamada "www" en el dominio "etcee.com". Asimismo, el nombre "etcee.com" nombra el dominio "etcee" en el dominio de nivel superior "com".

En LDAP, la situación es un poco más complicada. Los nombres se crean a partir de componentes separados por comas (","). Al igual que los nombres de DNS, se leen de derecha a izquierda. Sin embargo, los componentes de un nombre LDAP deben especificarse como pares de nombre / valor. El nombre "cn = Todd Sundsted, o = ComFrame, c = US" nombra a la persona "cn = Todd Sundsted" en la organización "o = ComFrame, c = US". Asimismo, el nombre "o = ComFrame, c = US" nombra la organización "o = ComFrame" en el país "c = US".

Como ilustran los ejemplos anteriores, la convención de denominación de un servicio de denominación por sí sola tiene el potencial de introducir una cantidad significativa del sabor del servicio de denominación subyacente en JNDI. Esta no es una característica que deba tener una interfaz independiente de la implementación.

JNDI resuelve este problema con la Nameclase y sus subclases y clases auxiliares. La Nameclase representa un nombre compuesto por secuencias ordenadas de subnombres y proporciona métodos para trabajar con nombres independientes del servicio de nombres subyacente.

Una mirada a la denominación JNDI

Como mencioné anteriormente, es importante recordar que JNDI es una interfaz en lugar de una implementación. Este hecho tiene algunas desventajas: necesita acceso a un servicio de nombres existente (como un servicio LDAP) y necesita comprender algo sobre cómo funciona para poder jugar con JNDI. Por otro lado, permite que JNDI se integre sin problemas en un entorno informático existente donde predomina un servicio de nombres establecido.

La denominación JNDI gira en torno a un pequeño conjunto de clases y un puñado de operaciones. Echemos un vistazo a ellos.

Contexto y contexto inicial

La Contextinterfaz juega un papel central en JNDI. Un contexto representa un conjunto de enlaces dentro de un servicio de nombres que comparten la misma convención de nombres. Un Contextobjeto proporciona los métodos para vincular nombres a objetos y desvincular nombres de objetos, para cambiar el nombre de los objetos y para enumerar las vinculaciones.

Algunos servicios de nombres también proporcionan funcionalidad de subcontexto. Al igual que un directorio en un sistema de archivos, un subcontexto es un contexto dentro de un contexto. Esta estructura jerárquica permite una mejor organización de la información. Para los servicios de nombres que admiten subcontextos, la Contextclase también proporciona métodos para crear y destruir subcontextos.

JNDI realiza todas las operaciones de denominación relativas a un contexto. Para ayudar a encontrar un lugar para comenzar, la especificación JNDI define una InitialContextclase. Esta clase se instancia con propiedades que definen el tipo de servicio de nombres en uso y, para los servicios de nombres que brindan seguridad, el ID y la contraseña para usar al conectarse.

Para aquellos que estén familiarizados con la Namingclase RMI , muchos de los métodos proporcionados por la Contextinterfaz que se describe a continuación les resultarán familiares. Echemos un vistazo a Contextlos métodos de ':

  • void bind(String stringName, Object object): Vincula un nombre a un objeto. El nombre no debe estar vinculado a otro objeto. Todos los contextos intermedios ya deben existir.

  • void rebind(String stringName, Object object): Vincula un nombre a un objeto. Todos los contextos intermedios ya deben existir.

  • Object lookup(String stringName): Devuelve el objeto especificado.

  • void unbind(String stringName): Unbinds the specified object.

The Context interface also provides methods for renaming and listing bindings.

  • void rename(String stringOldName, String stringNewName): Changes the name to which an object is bound.
  • NamingEnumeration listBindings(String stringName): Returns an enumeration containing the names bound to the specified context, along with the objects and the class names of the objects bound to them.

  • NamingEnumeration list(String stringName): Returns an enumeration containing the names bound to the specified context, along with the class names of the objects bound to them.

Each of these methods has a sibling that takes a Name object instead of a String object. A Name object represents a generic name. The Name class allows a program to manipulate names without having to know as much about the specific naming service in use.

The example

The example below illustrates how to connect to a naming service, list all of the bindings, or list a specific binding. It uses the filesystem service provider, which is one of the reference JNDI service-provider implementations provided by Sun. The filesystem service provider makes the filesystem look like a naming service (which it is, in many ways -- filenames like /foo/bar/baz are names and are bound to objects like files and directories). I selected it because everyone has access to a filesystem (as opposed to, say, an LDAP server).

import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.Binding; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import java.util.Hashtable; public class Main { public static void main(String [] rgstring) { try { // Create the initial context. The environment // information specifies the JNDI provider to use // and the initial URL to use (in our case, a // directory in URL form -- file:///...). Hashtable hashtableEnvironment = new Hashtable(); hashtableEnvironment.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory" ); hashtableEnvironment.put( Context.PROVIDER_URL, rgstring[0] ); Context context = new InitialContext(hashtableEnvironment); // If you provide no other command line arguments, // list all of the names in the specified context and // the objects they are bound to. if (rgstring.length == 1) { NamingEnumeration namingenumeration = context.listBindings(""); while (namingenumeration.hasMore()) { Binding binding = (Binding)namingenumeration.next(); System.out.println( binding.getName() + " " + binding.getObject() ); } } // Otherwise, list the names and bindings for the // specified arguments. else { for (int i = 1; i < rgstring.length; i++) { Object object = context.lookup(rgstring[i]); System.out.println( rgstring[i] + " " + object ); } } context.close(); } catch (NamingException namingexception) { namingexception.printStackTrace(); } } } 

The program in the listing above first creates an initial context from the specified JNDI provider (in this case, Sun's filesystem provider) and a URL specifying a local directory. If no additional command-line arguments are specified, the program lists the objects and names of every entity in the specified directory. Otherwise, it lists the objects and names of only those items specified on the command line.

Conclusion

You should now have both an understanding of and an appreciation for naming services in general and JNDI in particular. In distributed environments, they are valuable tools for locating information and resources. JNDI makes it possible to work with a variety of naming services without having to master a multitude of APIs. Next month, we'll take a look at the other half of JNDI -- its directory functions.

Todd Sundsted ha estado escribiendo programas desde que las computadoras estuvieron disponibles en convenientes modelos de escritorio. Aunque originalmente estaba interesado en construir aplicaciones distribuidas en C ++, Todd pasó al lenguaje de programación Java cuando se convirtió en la opción obvia para ese tipo de cosas. Además de escribir, Todd también trabaja como arquitecto de Java con el software ComFrame.

Más información sobre este tema

  • Descargue el código fuente completo de este artículo, en formato zip

    //images.techhive.com/downloads/idge/imported/article/jvw/2000/01/jw-01-howto.zip

  • Todas las cosas JNDI

    //java.sun.com/products/jndi/

  • Documentación JNDI

    //java.sun.com/products/jndi/docs.html

  • Proveedores de servicios disponibles actualmente

    //java.sun.com/products/jndi/serviceproviders.html

  • Lista completa de columnas Java de procedimientos anteriores

    //www.javaworld.com/javaworld/topicalindex/jw-ti-howto.html

Esta historia, "Descripción general de JNDI, Parte 1: Introducción a los servicios de nombres" fue publicada originalmente por JavaWorld.