2009-12-01 14 views
11

ho un problema con Java RMI:collegamento Rmi rifiutato con localhost

Quando sto cercando di eseguire il mio server, ho un ConnectException (vedi sotto).

eccezione accade quando l'esecuzione del metodo rebind:

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

utilizzando rmi: // localhost: 2020/RemoteDataPointHandler invece, non funziona neanche. Anche l'uso della porta predefinita non funziona. Ho anche provato a utilizzare l'indirizzo IP 127.0.0.1, ma con lo stesso effetto.

miei args runtime:

-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

Direi che hai un problema di temporizzazione qui. Il registro non è stato completamente avviato quando si esegue il rebind. – EJP

risposta

5

Sembra funzionare quando si sostituisce la

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

da

LocateRegistry.createRegistry(2020); 

chiunque un idea del perché? Qual è la differenza?

+4

Il secondo lo avvia come oggetto remoto nella JVM corrente. Innanzitutto avvia un processo separato. – EJP

5

È necessario disporre di un rmiregistry in esecuzione prima di tentare di connettere (registrare) un servizio RMI con esso.

La chiamata al metodo LocateRegistry.createRegistry(2020) crea ed esporta un registro sul numero di porta specificato.

Vedere la documentazione per LocateRegistry

+0

Lui sì, guarda il suo codice. – EJP

11

ha avuto un problema simliar con questa eccezione connessione. viene lanciato quando il registro non è ancora stato avviato (come nel tuo caso) o quando il registro non è ancora stato esportato (come nel mio caso).

ma un breve commento alla differenza tra i 2 modi per avviare il Registro di sistema:

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

corre il rmiregistry.exe in Javas bin-directory in un nuovo processo e continua in parallelo con il codice Java.

LocateRegistry.createRegistry(2020); 

la chiamata al metodo rmi inizia il Registro di sistema, restituisce il riferimento a tale registro remoto dell'oggetto e quindi continua con l'istruzione successiva.

nel tuo caso il Registro di sistema non viene avviato nel momento in cui si tenta di vincolare il proprio oggetto

+0

Grazie per la spiegazione! – Fortega

1

Una differenza si nota in Windows è:

Se si utilizza Runtime.getRuntime().exec("rmiregistry 1024");

si può vedere rmiregistry processo .exe verrà eseguito nel Task manager

mentre se si utilizza Registry registry = LocateRegistry.createRegistry(1024);

non è possibile vedere il processo in esecuzione in Task Manager,

Penso che Java lo gestisca in un modo diverso.

e questo è il mio file server.policy

Prima di eseguire l'applicazione, assicurarsi che hai ucciso tutti i tuoi javaw.exe esistente e rmiregistry.exe corrispondente alla RMI programmi che sono già in esecuzione.

Il seguente codice funziona per me utilizzando Registry.LocateRegistry() o

argomento
Runtime.getRuntime.exec(""); 


// Standard extensions get all permissions by default 

grant { 
    permission java.security.AllPermission; 
}; 

VM

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

Codice:

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

sembra che si dovrebbe impostare il vostro comando come un String[] , ad esempio:

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

proprio come lo stile di main(String[] args).

Problemi correlati