2010-12-07 6 views
0

Ich habe ein seltsames und zeitweiliges Problem beim Erstellen einer RMI-Registrierung aus der JVM. Dieser Code wird in einem Intranet ausgeführt, und die Idee besteht darin, Dienste auf einer Reihe von Computern problemlos starten zu können.RMI createRegistry Verzögerungsproblem

public static <X, Y> void newServer(Function<X, Y> function, String name) 
    throws Exception { 
    FunctionServer<X, Y> fun = null; 
    RemoteFunction<X, Y> stub = null; 
    Registry registry = null; 
    try { 
    fun = new FunctionServer<X, Y>(function); 
    stub = (RemoteFunction<X, Y>) UnicastRemoteObject.exportObject(fun, 0); 
    } 
    catch (RemoteException e1) { 
    e1.printStackTrace(); 
    } 

    boolean foundPort = false; 
    int port = 1099; 
    do { 
    try { 
     registry = LocateRegistry.createRegistry(port); 
     registry.rebind(name, stub); 
     // Thread.sleep(100); 
     foundPort = true; 
    } 
    catch (ExportException e) { 
     port++; 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
     throw e; 
    } 
    } while (!foundPort); 
    if (registry.lookup(name) != null) 
    System.out.println("Service " + name + " serving " 
     + function.getClass().getCanonicalName() + " on port " + port); 
} 

ist natürlich Es gibt eine sehr einfache Methode main:

FileSystemXmlApplicationContext context = 
    new FileSystemXmlApplicationContext(args[0]); 
Object obj = context.getBean(args[1]); 
if (obj instanceof Function<?, ?>) { 
    Function<?, ?> fun = (Function<?, ?>) obj; 
    FunctionServer.newServer(fun, args[2]); 
} 

Der Code von der Kommandozeile aufgerufen wird, wie folgt:

java -cp daopt.jar -Djava.rmi.server.codebase="file://daopt.jar" ****.*******.remote.FunctionServer spring/rosenbrockServer.xml rosenbrock rosenbrock 

Manchmal, wenn es leise ausfällt. Es druckt die erfolgreiche Server-Startnachricht, aber dann wird kein Java-Prozess ausgeführt, und netstat -anp | grep [portNumber] zeigt nichts an. Bemerkenswerterweise, wenn ich eine Verzögerung in das newServer-Verfahren einfüge, d. H. Die Zeile

auskommentieren, alles funktioniert gut. Bedeutet dies, dass LocateRegistry.createRegistry eine Art von Worker-Thread startet, der nach einiger Zeit eine Ausnahme auslöst? Was ist los?

flummoxed,
Dev

Antwort

0

Sprechen Sie die 'Registrierung' Variable ein statisches Element. Im Moment wird es als Müll gesammelt, der es exportiert, und erlaubt dem Server, DGC'd zu sein, wodurch der Prozess beendet werden kann.

Sie brauchen diese Do/While-Schleife nicht. Verwenden Sie Registrierung.REGISTRY_PORT. Dafür ist es da. Reserviert bei IANA für die RMI-Registrierung.

+0

Aha nutzen zu können! Gute! Anstatt es statisch zu machen, habe ich es endgültig gemacht. Das hat es behoben. Vielen Dank! – dgorur

+0

Ich brauche immer noch die Portnummer, weil es andere RMI-Registrierungen auf Port 1099 geben kann. – dgorur

+0

Machen Sie es statisch. Ich gab die Gründe an. Es endgültig zu machen, bringt diese nicht in Ordnung. – EJP

-1

Wenn LocateRegistry.createRegistry innerhalb der JVM verwenden, ist es ratsam,

final Registry registry = LocateRegistry.createRegistry(port); 
+0

* Warum * ist das ratsam? Zuerst habe ich davon in 12 Jahren RMI gehört. – EJP

+0

Hmm, wenn der Grund ist, dass es GC'ed wird, macht die Variable final das verhindern, nein? Warum etwas statisch machen, wenn es nicht sein muss? Angesichts der Tatsache, dass es nur eine Registrierung pro JVM gibt, ist es dasselbe, nehme ich an. – dgorur

+0

Nein, eine lokale Variable final wird * nicht daran gehindert, GC'd zu werden. Es statisch werden lassen. – EJP