2010-12-07 32 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); 
} 

非常に簡単な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]); 
} 

次のようにコードは、コマンドラインから起動されます。

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がしばらくしてから例外をスローする何らかの種類のワーカースレッドを起動していることを意味しますか?どうしたの?

Flummoxed、
のDev

答えて

0

は静的メンバ 'レジストリ' は可変ください。現時点ではガベージコレクションが行われているため、ガベージコレクタはそれをエクスポートし、サーバーをDGCにしてプロセスを終了させます。

do/whileループは必要ありません。 Registry.REGISTRY_PORTを使用してください。それがそれのためのものです。 RMIレジストリのIANAで予約されています。 JVM内LocateRegistry.createRegistryを使用する場合

+0

アハを使用することをお勧めです!いいです!それを静的にするのではなく、私はそれを最終的にしました。それはそれを修正した。本当にありがとう! – dgorur

+0

ポート番号が必要なのは、ポート1099に他のRMIレジストリがある可能性があるからです。 – dgorur

+0

静的にします。私は理由を述べた。それを最終的にすることはそれらを修正しない。 – EJP

-1

、それは

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

*なぜそれがお勧めですか?まず、12年間のRMIでそれについて聞いたことがあります。 – EJP

+0

ええ、もしそれがGCで処理されているのであれば、変数をfinalにするとそのことを防ぐでしょうか?なぜそれが必要でない場合静的なものを作るのですか? JVMあたりレジストリが1つしかないことを考えれば、それは同じことになります。 – dgorur

+0

いいえ、ローカル変数finalを*作成してもGCは実行されません。静的にする。 – EJP

関連する問題