2017-05-03 265 views
0

在服務器中,我運行帶有RMI服務器jar文件的docker容器。 我已經嘗試了幾種不同的配置,但我不能讓它工作。 我Serverside集團:Docker容器中的Java RMI服務器

public class Main extends UnicastRemoteObject implements RmiServerIntf { 


public static final String MESSAGE = "Hello World from docker in RMI"; 

public Main() throws RemoteException { 
    super(0); // required to avoid the 'rmic' step, see below 
} 

public String getMessage() { 
    return MESSAGE; 
} 

public static void main(String args[]) throws Exception { 
     System.out.println("RMI server started"); 
     System.setProperty("java.rmi.server.hostname", "<host-ip-address>"); 

     try { //special exception handler for registry creation 
      LocateRegistry.createRegistry(1099); 
      System.out.println("java RMI registry created."); 
     } catch (RemoteException e) { 
      LocateRegistry.getRegistry(); 
      System.out.println("java RMI registry already exists."); 
     } 

     //Instantiate RmiServer 

     Main obj = new Main(); 

     // Bind this object instance to the name "RmiServer" 
     Naming.rebind("RmiServer", obj); 
     System.out.println("PeerServer bound in registry"); 
} 

}

我的客戶:

public class Main { 


public Main() { 
} 

public static void main(String[] args) throws RemoteException, NotBoundException, MalformedURLException { 
    RmiServerIntf obj = (RmiServerIntf) Naming.lookup("rmi://<my-host-address>:4023/RmiServer"); 
    System.out.println(obj.getMessage()); 
} 

}

,他們都共享 「RmiServerIntf」

我Dockerfile:

FROM ubuntu:latest 

RUN回聲 「更新ubuntu的圖像」 RUN易於得到更新& &易於得到安裝-y \ 的openjdk -8- JRE EXPOSE 1099 COPY RMIServer.jar /home/RMIServer.jar CMD [的 「java」, 「罐子」, 「/home/RMIServer.jar」]

(對不起,它不會格式化右)

我開始我的容器: 搬運工運行--name rmitest -d -p 4023:1099 rmitestimage

客戶拋出我:

Exception in thread "main" java.rmi.ConnectException: Connection refused to host: <my-host-address>; nested exception is: 
java.net.ConnectException: Connection refused (Connection refused) 
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619) 
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216) 
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202) 
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:130) 
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:227) 
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:179) 
at com.sun.proxy.$Proxy0.getMessage(Unknown Source) 
at com.company.Main.main(Main.java:19) 
+0

'LocateRegistry.getRegistry();'的成功執行並不能證明註冊表存在,因爲它不執行任何網絡操作。如果你調用'LocateRegistry.createRegistry()',你必須將結果存儲到一個靜態變量中。 – EJP

回答

1

如果您從相同的JVM將同一端口上的註冊表和遠程對象導出,您將克服端口問題。您不需要使用套接字工廠。

static Registry registry; 

// ... 
registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT); 
// ... 
public Main() throws RemoteException 
{ 
    super(Registry.REGISTRY_PORT); 
    // ... 
} 

// .... 
Main main = new Main(); 
registry.rebind("RmiServer", main); 
+0

非常感謝。這個答案昨天就是黃金。我最終用UnicastRemoteObject.exportObject(obj,port)做了一些混亂的解決。但你的看起來很乾淨。稍後我會試一試。 – OhLongJohnJohnson

-1

它已經開始了在RMI只使用rmiregistry中端口初始化連接我的知識和實際的數據傳輸是發生在隨機端口。

因爲docker只允許連接到你明確鏈接到主機的端口,RMI服務器端的初始化正在發生,但方法調用的實際數據傳輸是「阻塞的」。 這個問題應該可以通過定製的RMI套接字工廠來克服。如果我成功了,我會回覆並回答。

+0

這是不正確的。 RMI使用註冊表獲取存根,並通過連接完成。存根然後通過同一個或另一個連接與遠程對象通信到同一端口或另一個端口。 – EJP