Pergunta

Para RMI no lado do servidor, precisamos iniciar o programa rmiregistry, ou apenas LocateRegistry.createRegistry chamada? Se ambos são possíveis, quais são as vantagens e desvantagens?

Foi útil?

Solução

Eles são a mesma coisa ... rmiregistry é um programa separado, que pode ser executado a partir de uma linha de comando ou um script, enquanto LocateRegistry.createRegistry faz a mesma coisa programaticamente.

Na minha experiência, para os servidores "reais" que você vai querer usar rmiregistry de modo que você sabe que está sempre correndo, independentemente de haver ou não o aplicativo cliente é iniciado. createRegistry é muito útil para testes, como você pode iniciar e parar o registro do seu teste, se necessário.

Outras dicas

Se começarmos rmiregistry primeiro, RmiServiceExporter iria registrar-se para o rmiregistry execução. Neste caso, temos que definir a propriedade do sistema 'java.rmi.server.codebase' para onde a classe 'org.springframework.remoting.rmi.RmiInvocationWrapper_Stub' pode ser encontrado. Caso contrário, o RmiServiceExporter não ser iniciado e tem a exceção " classe ClassNotFoundException não encontrado: org.springframework.remoting.rmi.RmiInvocationWrapper_Stub; exceção aninhada é: ... "

Se o seu servidor RMI, o cliente rmi e rmiregistry pode acessar o mesmo sistema de arquivos, você pode querer a propriedade do sistema ser configurado automaticamente para onde a spring.jar podem ser encontrados no sistema de arquivos compartilhado. O show de configuração seguintes classes utilitárias e primavera como isso pode ser alcançado.

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>

O exemplo mostra acima como a propriedade do sistema seja ajustada automaticamente apenas quando o servidor RMI, o cliente rmi e registro RMI pode acessar o mesmo sistema de arquivos. Se isso não é verdade ou primavera base de código é compartilhado através do outro método (por exemplo, HTTP), você pode modificar o CodeBaseResolver para caber sua necessidade.

Se você estiver escrevendo um aplicativo independente java você gostaria de iniciar o seu próprio rmiregistry mas se você estiver escrevendo um aplicativo J2EE que, obviamente, é executado dentro de um recipiente J2EE, então você quer "LocateRegistry", como já existe uma execução no aplicativo servidor!

Se você usar o Spring para exportar seus serviços RMI, ele inicia automaticamente um registo se não estiver em execução. Consulte RmiServiceExporter

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top