RMI 서버:rmiregistry 또는 LocateRegistry.createRegistry
-
01-07-2019 - |
문제
서버측 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