2010-12-07 91 views
0

我在JVM中創建RMI註冊表時遇到了一個奇怪而間歇的問題。這些代碼將全部在內部網上運行,並且想法是能夠輕鬆地在一堆機器上啓動服務。RMI createRegistry延遲問題

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); 
} 

當然有一個很簡單的主要方法:

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]); 
} 

該代碼是通過命令行調用如下:

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

然而,有時它靜靜地失敗。它打印成功的服務器啓動消息,但之後沒有運行java進程,並且netstat -anp | grep [portNumber]什麼也不顯示。值得注意的是,如果我延遲newServer方法,即取消註釋行

Thread.sleep(100); 

它一切正常。這是否意味着LocateRegistry.createRegistry正在啓動一段時間後會引發異常的工作線程?這是怎麼回事?

狼狽,
開發

回答

0

充分利用 '登記' 系統變量的靜態成員。目前正在進行垃圾收集,並取消了它,並允許服務器進行DGC'd,這允許進程退出。

你不需要做/ while循環。使用Registry.REGISTRY_PORT。這就是它的目的。在IANA爲RMI註冊處保留。

+0

啊哈!好的!我沒有把它做成靜態的,而是最終決定的。這解決了它。謝謝一堆! – dgorur 2010-12-07 02:04:45

+0

我仍然需要端口號,因爲端口1099上可能存在其他RMI註冊表。 – dgorur 2010-12-07 02:06:06

-1

當使用JVM內LocateRegistry.createRegistry,它建議使用

final Registry registry = LocateRegistry.createRegistry(port);