Java Language RMI attraverso JNDI

Esempio

Questo esempio mostra come funziona JNDI in RMI. Ha due ruoli:

  • per fornire al server un'API di binding / unbind / rebind al registro RMI
  • per fornire al client un'API di ricerca / elenco per il registro RMI.

Il registro RMI è parte di RMI, non JNDI.

Per semplificare, useremo java.rmi.registry.CreateRegistry() per creare il registro RMI.

  1. Server.java (il server JNDI)

    package com.neohope.jndi.test;
    
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    import java.io.IOException;
    import java.rmi.RemoteException;
    import java.rmi.registry.LocateRegistry;
    import java.util.Hashtable;
    
    /**
     * JNDI Server
     * 1.create a registry on port 1234
     * 2.bind JNDI
     * 3.wait for connection
     * 4.clean up and end
     */
    public class Server {
        private static Registry registry;
        private static InitialContext ctx;
    
        public static void initJNDI() {
            try {
                registry = LocateRegistry.createRegistry(1234);
                final Hashtable jndiProperties = new Hashtable();
                jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
                jndiProperties.put(Context.PROVIDER_URL, "rmi://localhost:1234");
                ctx = new InitialContext(jndiProperties);
            } catch (NamingException e) {
                e.printStackTrace();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    
        public static void bindJNDI(String name, Object obj) throws NamingException {
            ctx.bind(name, obj);
        }
    
        public static void unbindJNDI(String name) throws NamingException {
            ctx.unbind(name);
        }
    
        public static void unInitJNDI() throws NamingException {
            ctx.close();
        }
    
        public static void main(String[] args) throws NamingException, IOException {
            initJNDI();
            NMessage msg = new NMessage("Just A Message");
            bindJNDI("/neohope/jndi/test01", msg);
            System.in.read();
            unbindJNDI("/neohope/jndi/test01");
            unInitJNDI();
        }
    }
    
  2. Client.java (il client JNDI)

    package com.neohope.jndi.test;
    
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    import java.util.Hashtable;
    
    /**
     * 1.init context
     * 2.lookup registry for the service
     * 3.use the service
     * 4.end
     */
    public class Client {
        public static void main(String[] args) throws NamingException {
            final Hashtable jndiProperties = new Hashtable();
            jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
            jndiProperties.put(Context.PROVIDER_URL, "rmi://localhost:1234");
    
            InitialContext ctx = new InitialContext(jndiProperties);
            NMessage msg = (NeoMessage) ctx.lookup("/neohope/jndi/test01");
            System.out.println(msg.message);
            ctx.close();
        }
    }
    
  3. NMessage.java (classe server RMI)

    package com.neohope.jndi.test;
    
    import java.io.Serializable;
    import java.rmi.Remote;
    
    /**
     * NMessage
     * RMI server class
     * must implements Remote and Serializable 
     */
    public class NMessage implements Remote, Serializable {
        public String message = "";
    
        public NMessage(String message)
        {
            this.message = message;
        }
    }
    

Come eseguire l'eaxmple:

  1. costruire e avviare il server
  2. costruire e avviare il client

Introdurre

Modello JNDI

JNDI (Java Naming and Directory Interface) è un'API Java per un servizio di directory che consente ai client software Java di rilevare e cercare dati e oggetti tramite un nome. È progettato per essere indipendente da qualsiasi specifica implementazione di servizi di denominazione o directory.

L'architettura JNDI è costituita da un'API (Application Programming Interface) e da una SPI (Service Provider Interface). Le applicazioni Java utilizzano questa API per accedere a una varietà di servizi di denominazione e directory. L'SPI consente di collegare in modo trasparente un'ampia gamma di servizi di denominazione e directory, consentendo all'applicazione Java che utilizza l'API della tecnologia JNDI di accedere ai propri servizi.

Come puoi vedere dall'immagine qui sopra, JNDI supporta LDAP, DNS, NIS, NDS, RMI e CORBA. Certo, puoi estenderlo.

Come funziona

In questo esempio, Java RMI utilizza l'API JNDI per cercare oggetti in una rete. Se vuoi cercare un oggetto, hai bisogno di almeno due informazioni:

  • Dove trovare l'oggetto

Il registro RMI gestisce i collegamenti dei nomi, ti dice dove trovare l'oggetto.

  • Il nome dell'oggetto

Qual è il nome di un oggetto? Di solito è una stringa, può anche essere un oggetto che implementa l'interfaccia Nome.

Passo dopo passo

  1. Per prima cosa è necessario un registro, che gestisca il binding del nome. In questo esempio, usiamo java.rmi.registry.LocateRegistry .

    //This will start a registry on localhost, port 1234
    registry = LocateRegistry.createRegistry(1234);
    
  2. Sia il client che il server hanno bisogno di un contesto. Il server usa il contesto per associare il nome e l'oggetto. Il client usa il contesto per cercare il nome e ottenere l'oggetto.

    //We use com.sun.jndi.rmi.registry.RegistryContextFactory as the InitialContextFactory
    final Hashtable jndiProperties = new Hashtable();
    jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
    //the registry usrl is "rmi://localhost:1234"
    jndiProperties.put(Context.PROVIDER_URL, "rmi://localhost:1234");
    InitialContext ctx = new InitialContext(jndiProperties);
    
  3. Il server associa il nome e l'oggetto

    //The jndi name is "/neohope/jndi/test01"
    bindJNDI("/neohope/jndi/test01", msg);
    
  4. Il client cerca l'oggetto con il nome "/ neohope / jndi / test01"

    //look up the object by name "java:com/neohope/jndi/test01"
    NeoMessage msg = (NeoMessage) ctx.lookup("/neohope/jndi/test01");
    
  5. Ora il client può usare l'oggetto

  6. Al termine del server, è necessario pulire.

    ctx.unbind("/neohope/jndi/test01");
    ctx.close();