문제

서버측 RMI의 경우 시작해야 합니까? rmiregistry 프로그램을 작성하거나 전화로 문의하세요. LocateRegistry.createRegistry?둘 다 가능하다면 장점과 단점은 무엇입니까?

도움이 되었습니까?

해결책

그들은 똑같은 것입니다 ... rmiregistry 명령줄이나 스크립트에서 실행할 수 있는 별도의 프로그램입니다. LocateRegistry.createRegistry 프로그래밍 방식으로 동일한 작업을 수행합니다.

내 경험에 따르면 "실제" 서버의 경우 사용하고 싶을 것입니다. rmiregistry 클라이언트 애플리케이션의 시작 여부에 관계없이 항상 실행되고 있음을 알 수 있습니다. createRegistry 필요에 따라 테스트에서 레지스트리를 시작하고 중지할 수 있으므로 테스트에 매우 유용합니다.

다른 팁

rmiregistry를 먼저 시작하면 RmiServiceExporter는 실행 중인 rmiregistry에 자신을 등록합니다.이 경우 시스템 속성 'java.rmi.server.codebase'를 'org.springframework.remoting.rmi.RmiInvocationWrapper_Stub' 클래스를 찾을 수 있는 위치로 설정해야 합니다.그렇지 않으면 RMiserviceExporter가 시작되지 않았으며 "ClassNotFoundException 클래스를 찾을 수 없습니다.org.springframework.remoting.rmi.RmiInvocationWrapper_Stub;중첩 예외는 다음과 같습니다...."

rmi 서버, rmi 클라이언트 및 rmiregistry가 동일한 파일 시스템에 액세스할 수 있는 경우 공유 파일 시스템에서 spring.jar을 찾을 수 있는 위치로 시스템 속성을 자동으로 구성할 수 있습니다.다음 유틸리티 클래스와 스프링 구성은 이를 달성하는 방법을 보여줍니다.

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>

위의 예는 rmi 서버, rmi 클라이언트 및 rmi 레지스트리가 동일한 파일 시스템에 액세스할 수 있는 경우에만 시스템 속성이 자동으로 설정되는 방법을 보여줍니다.그것이 사실이 아니거나 스프링 코드베이스가 다른 방법을 통해 공유되는 경우(예:HTTP), 필요에 맞게 CodeBaseResolver를 수정할 수 있습니다.

독립형 Java 애플리케이션을 작성하는 경우 자체 rmiregistry를 시작하고 싶지만 분명히 J2EE 컨테이너 내에서 실행되는 J2EE 앱을 작성하는 경우 앱 서버에서 이미 실행 중인 항목이 있으므로 "LocateRegistry"를 원할 것입니다!

Spring을 사용하여 RMI 서비스를 내보내는 경우 레지스트리가 아직 실행되지 않으면 자동으로 시작됩니다.보다 RmiServiceExporter

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top