-1

私はドキュメントを見て、テストし、デバッグしました...しかし、困惑したままです。スタックオーバーフローの時間!ステージを設定してから、エラーを説明します。

バックグラウンド

クライアント、サーバー、および rmiregistry がすべて localhost に一緒に存在する場合に正常に動作する RMI クライアント/サーバーのセットアップがあります。そこで、rmi.server.logCalls トレースをオンにして (以下では RegistryTrace と呼びます)、serverHost で rmiregistry を起動します。サーバー コードの重要な部分:

String hostname = "//serverHost.local/project"
String codeBase = "file:/home/rik/Code/eclipse/project/bin/"

System.setProperty("java.rmi.server.hostname", hostname);
System.setProperty("java.rmi.server.codebase", codeBase); 

Driver server = new Driver();
Naming.rebind(hostname, server);

サーバーを起動すると、rebind() 呼び出しが成功することがわかります (RegistryTrace を見ると)。また、Naming.list() によって生成されたリストを見ると、「//serverHost.local:1099/project」が含まれていることがわかります

クライアントを起動すると、Naming.lookup() が正常に完了します。

server = (ServerInterface)Naming.lookup(serverHost);

RegistryTrace を見ると、この lookup() クエリがサーバー側に到達していることを確認できます。

最初の RMI でのエラー

しかし今:私の次のステートメントはサーバーのメソッドの1つを呼び出そうとします

boolean status = server.initConnection(username);

IllegalArgumentException を生成します。

java.lang.IllegalArgumentException: protocol = socket host = null
at sun.net.spi.DefaultProxySelector.select(DefaultProxySelector.java:151)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:424)
at java.net.Socket.connect(Socket.java:529)
at java.net.Socket.connect(Socket.java:478)
at java.net.Socket.<init>(Socket.java:375)
at java.net.Socket.<init>(Socket.java:189)
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:595)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:110)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132)
at $Proxy0.initConnection(Unknown Source)
at project.client.View2.main(View2.java:651)

私はこれを Java ソースから java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod() への呼び出しまでたどりました。

   private Object invokeRemoteMethod(Object proxy,
                  Method method,
                  Object[] args)
throws Exception
{
try {
    if (!(proxy instanceof Remote)) {
    throw new IllegalArgumentException(
        "proxy not Remote instance");
    }

    // EXCEPTION OCCURS WITHIN CALL TO ref.invoke() BELOW
    //
    return ref.invoke((Remote) proxy, method, args,
              getMethodHash(method));

} catch (Exception e) {
    if (!(e instanceof RuntimeException)) {
    Class<?> cl = proxy.getClass();
    try {
        method = cl.getMethod(method.getName(),
                  method.getParameterTypes());
    } catch (NoSuchMethodException nsme) {
        throw (IllegalArgumentException)
        new IllegalArgumentException().initCause(nsme);
    }
    Class<?> thrownType = e.getClass();
    for (Class<?> declaredType : method.getExceptionTypes()) {
        if (declaredType.isAssignableFrom(thrownType)) {
        throw e;
        }
    }
    e = new UnexpectedException("unexpected exception", e);
    }
    throw e;
}
}

その後、ソース トレースでそれを失います。(sun.rmi.server.UnicastRef などのソースの可用性に関する話を知っている人はいますか?) 残りのトレースでは、RMI がソケットを作成できないように見えますか?

このコードの多くの部分がよりきれいになると確信しています。任意の提案をいただければ幸いです。また、これを jar ファイルのディストリビューションに変換する必要があるので、今すぐ java.rmi.server.codebase に指定した方が簡単でしょうか?

提案をありがとう、リク

4

1 に答える 1

0

これは SocksSocketImpl を構築しているため、クライアントで Socks.proxyHost/socks.proxyPort を介して無効な SOCKS プロキシ ホストまたはポートを指定している必要があります。または、サーバーで java.rmi.server.hostname を奇妙な値に設定している可能性があります。

于 2011-12-15T21:15:56.747 に答える