2009-12-01 10 views
11

mam problem z wykorzystaniem Java RMI:połączenie RMI odmówił z localhost

Kiedy próbuję uruchomić mój serwer, otrzymuję ConnectException (patrz niżej).

Wyjątek dzieje podczas wykonywania metody ponownego wiązania:

Runtime.getRuntime().exec("rmiregistry 2020"); 
MyServer server = new MyServer(); 
Naming.rebind("//localhost:2020/RemoteDataPointHandler", server); 

przy użyciu RMI: // localhost: 2020/RemoteDataPointHandler zamiast, to nie działa. Używanie domyślnego portu nie działa. Próbowałem również używać adresu IP 127.0.0.1, ale z tym samym efektem.

moje argumenty uruchomieniowe:

-Djava.security.policy=java.security.AllPermission 
 
Exception in thread "main" java.rmi.ConnectException: Connection refused to host: localhost; nested exception is: 
    java.net.ConnectException: Connection refused 
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574) 
    at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185) 
    at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171) 
    at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306) 
    at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source) 
    at java.rmi.Naming.rebind(Naming.java:160) 
    at be.fortega.knx.server.Main.(Main.java:25) 
    at be.fortega.knx.server.Main.main(Main.java:16) 
Caused by: java.net.ConnectException: Connection refused 
    at java.net.PlainSocketImpl.socketConnect(Native Method) 
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333) 
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195) 
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182) 
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:433) 
    at java.net.Socket.connect(Socket.java:524) 
    at java.net.Socket.connect(Socket.java:474) 
    at java.net.Socket.(Socket.java:371) 
    at java.net.Socket.(Socket.java:184) 
    at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22) 
    at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128) 
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:569) 
    ... 7 more 

+1

Powiedziałbym, że masz tu problem z regulacją czasu. Rejestr nie został całkowicie uruchomiony po zrobieniu rebind. – EJP

Odpowiedz

5

wydaje się działać, kiedy wymienić

Runtime.getRuntime().exec("rmiregistry 2020"); 

przez

LocateRegistry.createRegistry(2020); 

nikogo pomysł dlaczego? Co za różnica?

+4

Drugi uruchamia go jako obiekt zdalny w bieżącej maszynie JVM. Najpierw rozpoczyna się oddzielny proces. – EJP

5

Przed nawiązaniem połączenia (zarejestruj się) z usługą RMI musisz mieć uruchomioną rmiregistry.

Wywołanie metody tworzy i eksportuje rejestr o podanym numerze portu.

Patrz dokumentacja dla LocateRegistry

+0

On robi, widzi swój kod. – EJP

11

miał simliar problem z tym wyjątkiem połączeń. jest on wyrzucany, gdy rejestr nie jest jeszcze uruchomiony (tak jak w twoim przypadku) lub gdy rejestr jest już niedoszacowany (jak w moim przypadku).

ale krótki komentarz do różnicy między 2 sposoby, aby uruchomić rejestru:

Runtime.getRuntime().exec("rmiregistry 2020"); 

uruchamia rmiregistry.exe w Javas bin-katalogu w nowym procesie i nadal równolegle z kodem java.

Wywołanie metody rmi uruchamia rejestr, zwraca odwołanie do tego zdalnego obiektu rejestru, a następnie kontynuuje następną instrukcję.

w przypadku rejestru nie jest uruchamiany w momencie, gdy próbujesz powiązać obiekt

+0

Dzięki za wyjaśnienie! – Fortega

1

Jedną z różnic możemy zauważyć w Windows jest:

Jeśli używasz Runtime.getRuntime().exec("rmiregistry 1024");

widać rmiregistry proces .exe będzie działać w Menedżerze zadań

natomiast jeśli używasz Registry registry = LocateRegistry.createRegistry(1024);

nie można zobaczyć proces uruchomiony w Menedżerze zadań,

Myślę, że Java obsługuje go w inny sposób.

i to jest mój plik server.policy

Przed uruchomieniem aplikacji, upewnij się, że zabiłeś wszystkie istniejące javaw.exe i rmiregistry.exe odpowiada swoimi RMI programów, które są już uruchomiony.

Poniższy kod działa dla mnie za pomocą Registry.LocateRegistry() lub

Runtime.getRuntime.exec(""); 


// Standard extensions get all permissions by default 

grant { 
    permission java.security.AllPermission; 
}; 

VM argumentem

-Djava.rmi.server.codebase=file:\C:\Users\Durai\workspace\RMI2\src\ 

Kod:

package server;  

import java.rmi.Naming; 
import java.rmi.RMISecurityManager; 
import java.rmi.Remote; 
import java.rmi.registry.LocateRegistry; 
import java.rmi.registry.Registry; 

public class HelloServer 
{ 
    public static void main (String[] argv) 
    { 
    try { 

     if(System.getSecurityManager()==null){ 
      System.setProperty("java.security.policy","C:\\Users\\Durai\\workspace\\RMI\\src\\server\\server.policy"); 
      System.setSecurityManager(new RMISecurityManager()); 
     } 

Runtime.getRuntime().exec("rmiregistry 1024"); 

//  Registry registry = LocateRegistry.createRegistry(1024); 
    // registry.rebind ("Hello", new Hello ("Hello,From Roseindia.net pvt ltd!")); 
    //Process process = Runtime.getRuntime().exec("C:\\Users\\Durai\\workspace\\RMI\\src\\server\\rmi_registry_start.bat"); 

     Naming.rebind ("//localhost:1024/Hello",new Hello ("Hello,From Roseindia.net pvt ltd!")); 
     System.out.println ("Server is connected and ready for operation."); 
    } 
    catch (Exception e) { 
     System.out.println ("Server not connected: " + e); 
     e.printStackTrace(); 
    } 
    } 
} 
0

wydaje się, że należy ustawić komendę jako String[] , na przykład:

String[] command = new String[]{"rmiregistry","2020"}; 
Runtime.getRuntime().exec(command); 

to tak jak styl main(String[] args).

Powiązane problemy