Domanda

Per RMI sul lato server, è necessario avviare rmiregistry programma o semplicemente chiama LocateRegistry.createRegistry?Se entrambe le cose sono possibili, quali sono i vantaggi e gli svantaggi?

È stato utile?

Soluzione

Sono la stessa cosa... rmiregistry è un programma separato, che puoi eseguire da una riga di comando o da uno script, mentre LocateRegistry.createRegistry fa la stessa cosa a livello di programmazione.

Nella mia esperienza, per i server "reali" che vorrai utilizzare rmiregistry in modo da sapere che è sempre in esecuzione indipendentemente dal fatto che l'applicazione client sia avviata o meno. createRegistry è molto utile per i test, poiché puoi avviare e interrompere il registro dal test secondo necessità.

Altri suggerimenti

Se avviamo prima rmiregistry, RmiServiceExporter si registrerà nel rmiregistry in esecuzione.In questo caso, dobbiamo impostare la proprietà di sistema 'java.rmi.server.codebase' nel punto in cui si trova la classe 'org.springframework.remoting.rmi.RmiInvocationWrapper_Stub'.Altrimenti, il RMIServiceExporter non sarebbe stato avviato e ha ricevuto l'eccezione "ClassNoundException Class non trovata:org.springframework.remoting.rmi.RmiInvocationWrapper_Stub;l'eccezione nidificata è:..."

Se il tuo server rmi, il tuo client rmi e rmiregistry possono accedere allo stesso filesystem, potresti voler configurare automaticamente la proprietà del sistema nel punto in cui è possibile trovare spring.jar sul filesystem condiviso.Le seguenti classi di utilità e la configurazione della molla mostrano come ciò può essere ottenuto.

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>

L'esempio sopra mostra come la proprietà di sistema può essere impostata automaticamente solo quando il server rmi, il client rmi e il registro rmi possono accedere allo stesso filesystem.Se ciò non è vero o la base di codice Spring è condivisa tramite un altro metodo (ad es.HTTP), è possibile modificare CodeBaseResolver in base alle proprie esigenze.

Se stai scrivendo un'applicazione Java autonoma, vorresti avviare il tuo rmiregistry, ma se stai scrivendo un'app J2EE che ovviamente viene eseguita all'interno di un contenitore J2EE, allora vuoi "LocateRegistry" poiché ce n'è già uno in esecuzione sul server dell'app!

Se usi Spring per esportare i tuoi servizi RMI, avvia automaticamente un registro se non ne è già in esecuzione.Vedere RmiServiceExporter

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top