2008-10-27 4 views
7

자바 RMI 서버 다음방법 원격으로 종료 내가처럼 보이는 아주 간단한 자바 RMI 서버가

나는 종료 메소드를 호출
import java.rmi.*; 
    import java.rmi.server.*; 

    public class CalculatorImpl extends UnicastRemoteObject implements Calculator { 

     private String mServerName; 

     public CalculatorImpl(String serverName) throws RemoteException 
     { 
      super(); 
      mServerName = serverName; 
     } 

     public int calculate(int op1, int op2) throws RemoteException 
     { 
      return op1 + op2; 
     } 

     public void exit() throws RemoteException 
     { 
      try{ 
       Naming.unbind(mServerName); 
       System.out.println("CalculatorServer exiting."); 
      } 
      catch(Exception e){} 

      System.exit(1); 
     } 

     public static void main(String args[]) throws Exception 
     { 
      System.out.println("Initializing CalculatorServer."); 

      String serverObjName = "rmi://localhost/Calculator"; 

      Calculator calc = new CalculatorImpl(serverObjName); 

      Naming.rebind(serverObjName, calc); 

      System.out.println("CalculatorServer running."); 
     } 
} 

이 System.exit와 (1) 다음과 같은 예외가 발생합니다 :

CalculatorServer exiting. 
java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: 
     java.io.EOFException 
     at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:203) 
     at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:126) 
     at CalculatorImpl_Stub.exit(Unknown Source) 
     at CalculatorClient.<init>(CalculatorClient.java:17) 
     at CalculatorClient.main(CalculatorClient.java:29) 
Caused by: java.io.EOFException 
     at java.io.DataInputStream.readByte(DataInputStream.java:243) 
     at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:189) 
     ... 4 more 
[2]+ Exit 1     java CalculatorImpl 

이 방법으로 잘못된 것은 무엇입니까?

답변

15

누구나 비슷한 문제가 발생하면 직접 대답을 알아 냈습니다. 다음은 내 exit() 메소드입니다.

public void exit() throws RemoteException 
{ 
    try{ 
     // Unregister ourself 
     Naming.unbind(mServerName); 

     // Unexport; this will also remove us from the RMI runtime 
     UnicastRemoteObject.unexportObject(this, true); 

     System.out.println("CalculatorServer exiting."); 
    } 
    catch(Exception e){} 
} 
+0

unexportObject 예제에 감사드립니다. –

4

실제로 등록을 취소하고 즉시 System.exit를 호출하면 정상적으로 종료되지 않습니다. 기본적으로 클라이언트에게 메시지가 완료되었음을 알리기 전에 연결을 끊습니다. 스레드가 여전히 종료 방법에서 돌아 오는 동안 뭔가 미래에 일어나게 할 수 있도록 필요한

public void quit() throws RemoteException { 
    System.out.println("quit"); 
    Registry registry = LocateRegistry.getRegistry(); 
    try { 
    registry.unbind(_SERVICENAME); 
    UnicastRemoteObject.unexportObject(this, false); 
    } catch (NotBoundException e) { 
    throw new RemoteException("Could not unregister service, quiting anyway", e); 
    } 

    new Thread() { 
    @Override 
    public void run() { 
     System.out.print("Shutting down..."); 
     try { 
     sleep(2000); 
     } catch (InterruptedException e) { 
     // I don't care 
     } 
     System.out.println("done"); 
     System.exit(0); 
    } 

    }.start(); 
} 

: 어떻게 작동하는 등의 시스템을 종료 작은 스레드를 시작하는 것입니다.

+3

전체 스레드 부분은 좋은 생각이지만 필수는 아닙니다. UnicastRemoteObject.unexportObject (this, false) 대신 UnicastRemoteObject.unexportObject (this, true)를 설정하면됩니다. 방금 같은 문제를 시도했습니다. – Anonymous

+0

동일한 문제가있어서 unexportObject의 두 번째 매개 변수를 설정해도 도움이되지 않지만 Thread에서 System.exit을 실행하면 도움이되었습니다. – simon

관련 문제