programa example ejercicio ejemplo java rmi rmiregistry

example - rmi java ejemplo netbeans



Servidor RMI: rmiregistry o LocateRegistry.createRegistry (4)

Para RMI en el lado del servidor, ¿necesitamos iniciar el programa rmiregistry o simplemente llamar a LocateRegistry.createRegistry ? Si ambos son posibles, ¿cuáles son las ventajas y desventajas?


Si está escribiendo una aplicación java independiente, querrá iniciar su propio rmiregistry, pero si está escribiendo una aplicación J2EE que obviamente se ejecuta dentro de un contenedor J2EE, entonces quiere "LocateRegistry" ya que ya hay uno ejecutándose en el servidor de la aplicación.


Son lo mismo ... rmiregistry es un programa separado, que se puede ejecutar desde una línea de comandos o un script, mientras que LocateRegistry.createRegistry hace lo mismo programáticamente.

En mi experiencia, para servidores "reales" querrá usar rmiregistry para que sepa que siempre se está ejecutando, independientemente de si la aplicación del cliente está iniciada o no. createRegistry es muy útil para las pruebas, ya que puede iniciar y detener el registro de su prueba según sea necesario.


Si usa Spring para exportar sus servicios de RMI, automáticamente inicia un registro si uno no se está ejecutando. Ver RmiServiceExporter


Si comenzamos rmiregistry primero, RmiServiceExporter se registraría en el rmiregistry en ejecución. En este caso, debemos establecer la propiedad del sistema ''java.rmi.server.codebase'' en donde se puede encontrar la clase ''org.springframework.remoting.rmi.RmiInvocationWrapper_Stub''. De lo contrario, el RmiServiceExporter no se iniciaría y obtendría la excepción "Clase ClassNotFoundException no encontrada: org.springframework.remoting.rmi.RmiInvocationWrapper_Stub; la excepción anidada es: ..."

Si su servidor rmi, rmi client y rmiregistry pueden acceder al mismo sistema de archivos, puede desear que la propiedad del sistema se configure automáticamente donde se puede encontrar spring.jar en el sistema de archivos compartido. Las siguientes clases de utilidad y configuración de primavera muestran cómo se puede lograr esto.

abstract public class CodeBaseResolver { static public String resolveCodeBaseForClass(Class<?> clazz) { Assert.notNull(clazz); final CodeSource codeSource = clazz.getProtectionDomain().getCodeSource(); if (codeSource != null) { return codeSource.getLocation().toString(); } else { return ""; } } } public class SystemPropertyConfigurer { private Map<String, String> systemProperties; public void setSystemProperties(Map<String, String> systemProperties) { this.systemProperties = systemProperties; } @PostConstruct void init() throws BeansException { if (systemProperties == null || systemProperties.isEmpty()) { return; } for (Map.Entry<String, String> entry : systemProperties.entrySet()) { final String key = entry.getKey(); final String value = SystemPropertyUtils.resolvePlaceholders(entry.getValue()); System.setProperty(key, value); } } } <bean id="springCodeBase" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="staticMethod" value="xx.CodeBaseResolver.resolveCodeBaseForClass" /> <property name="arguments"> <list> <value>org.springframework.remoting.rmi.RmiInvocationWrapper_Stub</value> </list> </property> </bean> <bean id="springCodeBaseConfigurer" class="xx.SystemPropertyConfigurer" depends-on="springCodeBase"> <property name="systemProperties"> <map> <entry key="java.rmi.server.codebase" value-ref="springCodeBase" /> </map> </property> </bean> <bean id="rmiServiceExporter" class="org.springframework.remoting.rmi.RmiServiceExporter" depends-on="springCodeBaseConfigurer"> <property name="serviceName" value="XXX" /> <property name="service" ref="XXX" /> <property name="serviceInterface" value="XXX" /> <property name="registryPort" value="${remote.rmi.port}" /> </bean>

El ejemplo anterior muestra cómo la propiedad del sistema se establece automáticamente solo cuando el servidor rmi, el cliente rmi y el registro rmi pueden acceder al mismo sistema de archivos. Si eso no es cierto o la base de código de primavera se comparte a través de otro método (por ejemplo, HTTP), puede modificar el CodeBaseResolver para que se ajuste a sus necesidades.