2011-12-14 2 views
-1

Я смотрел документ, тестировал, отлаживал ... но оставался тугим. время для stackOverflow! я выложу сцену, а затем опишите свою ошибку.java.RMI гнездо создание подробности?

фон

У меня есть клиент RMI/разъединить установку, которая работает хорошо, когда клиент, сервер и rmiregistry жить все вместе на локальном хосте. поэтому я запускаю rmiregistry на сервереHost, с включенной трассировкой 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); 

, когда я запустить сервер, я вижу вызов повторного связывания() завершается успешно (посмотрев на 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 было бы проще ...?

спасибо за любые предложения, РИК

+0

http://jdk7src.sourceforge.net/ предоставляет файл src-jdk.zip, содержащий почти все классы, включенные в Oracle JDK 7 (все идентичные в OpenJDK7). Для JDK 6 вам нужно будет получить источник JRL (после принятия JRL) и скопировать их самостоятельно ... – mihi

+0

спасибо за указатель на jdk7src в sourceforge, mihi. но я пробил через [ссылку] SE6 скачать (http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u30-download-1377139.html), а также в [link] архивах (http : //www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase6-419409.html#jdk-6u29-oth-JPR), но не найти источник там? – rikb

+0

http://download.java.net/jdk6/source/ является последним «официальным» источником JRL для Java 6. Для более поздних версий просто начинайте, например. http://download.java.net/jdk6/6u30/и щелкните по файловой структуре, пока не найдете ее: D – mihi

ответ

0

Он возводит SocksSocketImpl, так что вы должны быть указания недействительные SOCKS прокси хост или порт через socks.proxyHost/socks.proxyPort у клиента, или, возможно, у вас есть java.rmi .server.hostname задано странным значением на сервере.

+0

thanks EJP! но как может случиться, что вызов Naming.lookup(), используя одно и то же имя хоста, работает? не использует ли он то же значение, что и RMI? – rikb

+0

@rikb Он использует все, что вы скажете, чтобы использовать его в URL-адресе поиска. Когда вы вызываете удаленный метод, он использует все, что сервер помещает в заглушку, на что влияет java.rmi.server.hostname. – EJP

+0

с использованием Naming.list() показывает, что он построен «//serverHost.local:1099/project», что кажется правильным? – rikb