java.RMI套接字创建细节?

时间:2011-12-14 23:02:58

标签: java sockets rmi rmiregistry

我看过doc,测试,调试......但仍然难过。 stackOverflow的时间!我将设置舞台,然后描述我的错误。

背景

我有一个RMI客户端/服务器设置,在客户端,服务器和rmiregistry时工作正常 所有人都住在localhost。所以我在serverHost上启动rmiregistry,打开rmi.server.logCalls跟踪(下面称为RegistryTrace)。服务器代码的重要部分:

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错误

但是现在:我的下一个语句试图调用服务器的一个方法

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指定它们会更容易......?

感谢任何建议,rik

1 个答案:

答案 0 :(得分:0)

它正在构建一个SocksSocketImpl,所以你必须在客户端通过socks.proxyHost / socks.proxyPort指定一个无效的SOCKS代理主机或端口,或者你可能将java.rmi.server.hostname设置为一个奇怪的值。服务器