2013-08-09 2 views
0

나는 자바 RMI에 익숙하다. 실제로 rmic을 컴파일하고 rmic를 시작했으며 또한 서버를 시작하려고했지만 _stub 'ClassNotFound'예외로 인해 실패했다. 자바 7을 사용하고있다. 구글에 많이 있지만 아무도 작동 할 수있는 예제 단계별로 말한 ... 나는 코드베이스와 보안 정책을 stteing에 대한 아이디어를 가지고 있지만 아주 명확하지 제안을 어떻게 .. 제발 명령 줄을 포함하여 단계를 말하는 데 도움이 ... ....... 제발 ... 나는 단지 서버를 시작하는 법을 알려주고 코드베이스 나 정책 설정 등과 같은 설정을 필요로합니다. 감사합니다.rmic 레지스트리 및 서버를 Java 1.7을 사용하여 시작하는 방법은 무엇입니까?

답변

-1

java 이후로 rmic 명령을 사용할 필요가 없습니다. (J2SE) 5.0 스텁은 런타임에 동적으로 생성됩니다.

다음은 RMI를 사용하는 기본 단계별 예제입니다.

먼저 클라이언트가보고 수행 할 수있는 작업을 정의하는 원격 인터페이스를 정의 :

public interface FooService extends Remote { 
    // Don't forget to add throws RemoteException. 
    public void bar() throws RemoteException; 
} 

참고 : 당신은 다음과 같은 예외가 발생합니다 메소드 선언에 throws RemoteException를 추가하지 않는 경우 :

java.lang.IllegalArgumentException: illegal remote method encountered: public abstract void RMIExample.FooService.bar() 

클라이언트가 수행 할 수있는 작업을 정의한 후 서버 슬라이드에서 메소드의 구체적인 구현을 정의해야합니다.

public class FooServiceImpl extends UnicastRemoteObject implements FooService { 
    public FooServiceImpl() throws RemoteException { 
     super(); 
    } 

    public void bar() { 
     System.out.println("I was remotely invoked!"); 
    } 
} 

구현 클래스는 UnicastRemoteObject에서 상속 받아 앞서 정의한 Remote 인터페이스를 구현해야하며 클래스에는 RemoteException을 throw하는 생성자가 있어야합니다. 이제 당신은 당신의 서버를 백업하고 일명 스텁 인스턴스를 필요로 실행을 가지고

// 4000 is the port to listen on. 
LocateRegistry.createRegistry(4000); 
Naming.rebind("//127.0.0.1:4000/foobar", new FooServiceImpl()); 

을 : 당신이 완전히 당신이 서버 측에서 URL로 구현 객체를 바인드해야합니다 원격 기능을 정의 이제

클라이언트 측에서 프록시 :

FooService fooService = 
     (FooService)Naming.lookup("//127.0.0.1:4000/foobar"); 

마침내 원격 메소드 호출 :

fooService.bar(); 
,369을

다음은 서버 측에 인쇄해야합니다

I was remotely invoked! 

참고 : rmic을 사용하는 당신은 필요가 없습니다

http://en.wikipedia.org/wiki/Java_remote_method_invocation http://docs.oracle.com/javase/1.5.0/docs/guide/rmi/relnotes.html

+0

구현 클래스는 UnicastRemoteObject를 확장 할 필요는 없지만 포트 번호를 사용하여 super()를 호출해야합니다. 그렇지 않으면 동적 프록시를 생성 할 수 없습니다. Naming.rebind ("// 0.0.0.0 ...,)는 '어디서나 연결 허용'을 의미하지 않을뿐만 아니라 전혀 작동하지 않습니다 -1 작동하지 않는 예제의 경우 – EJP

+0

@EJP 만약 ' t 하위 클래스 인 UnicastRemoteObject를 구현하고 java.io.Serializable을 FooServiceImpl에 구현하면 서버가 시작되어 실행되지만 Naming.lookup() 대신 스텁을 반환하면 메서드 대신 FooServceImpl의 직렬화 된 인스턴스가 반환됩니다. 클라이언트 컴퓨터에서 호출 된 원격 서버에서 호출 될 때 UnicastRemoteObject의 설명서에 "JRMP로 원격 객체를 내보내고 스텁을 얻는 데 사용됩니다."라고 쓰여지고 super()를 호출하면 레지스트리의 포트와 i –

+0

'Serializable '구현에 대해 한 마디도 말하지 않았다.'UnicastRemoteObject'를 서브 클래스 화하지 않으면, 당신이해야 할 일은'UnicastRemoteObject.exportObject ()'를 클릭하여 객체를 다시 객체로 내 보냅니다. 모트 개체. 그게 그 방법입니다. 이것은 모두 [Javadoc] (http://docs.oracle.com/javase/7/docs/api/java/rmi/server/UnicastRemoteObject.html)과 [RMI Specification # 5.3.1] (http : //docs.oracle.com/javase/7/docs/platform/rmi/spec/rmi-server24.html). – EJP

1

합니다. 대신 서버 개체를 만들고 port 매개 변수가있는 exportObject() 메서드 오버로드 중 하나를 호출하십시오. 예를 들어

MyRemoteIntf stub = UnicastRemoteObject.exportObject(server, 0); 

이렇게하면 RMI가 자동으로 스텁을 생성합니다. port 매개 변수없이이 버전을 사용하면 자동으로 생성하는 대신 이전의 rmic 생성 스텁 만 사용합니다 (이 점에 관해서는 설명서가 끔찍하게 명확하지 않습니다.))

또한 원격 인터페이스가 레지스트리와 클라이언트 모두의 코드베이스에 있는지 확인하십시오. 제대로하지 않으면 다른 오류가 발생합니다. 이것은 이미 Stackoverflow에서 여러 번 답변되었습니다; "rmi ClassNotFoundException"을 검색하십시오.

+0

[끔찍하게 불명확 한 문서] (http://docs.oracle.com/javase/7/docs/api/java/rmi/server/UnicastRemoteObject.html)에서는 이렇게 말합니다. "원격 객체를 UnicastRemoteObject.exportObject (Remote) 메소드, 스텁 클래스 (일반적으로 rmic 툴을 사용해 원격 객체 클래스로부터 미리 생성)가로드됩니다. – EJP

+0

** 행동 **이 ** 문서화되어있는 것이 맞습니다. 그러나 ['exportObject (Remote)'에 대한 문서 비교 (http://docs.oracle.com/javase/7/docs/api/java/rmi/server/UnicastRemoteObject.html#exportObject%28java.rmi.Remote% 29) 및 ['exportObject (Remote, int)'] (http://docs.oracle.com/javase/7/docs/api/java/rmi/server/UnicastRemoteObject.html#exportObject%28java.rmi.Remote, % 20int % 29). 스텁 처리의 차이에 대한 언급은 없습니다. 네트워킹에 관한'port' 매개 변수의 추가가 스텁의 처리를 근본적으로 바꿔 놓는 것은 매우 직관이 아닙니다. –

+0

요즘에는이 문제를 해결하고 싶습니다. 어떤 제안? –