Java RMI UnmarshalException и сервер AWS EC2

Я пытаюсь реализовать руководство по RMI Compute PI, которое можно найти на веб-сайте Sun / Oracle здесь. Сервер расположен на сервере Amazon Windows EC2. Клиент находится на моем персональном компьютере дома. Для простоты я отключил брандмауэр на сервере и открыл все порты в группе безопасности EC2. Я могу пинговать машину, иметь доступ к файлам и т. Д. Моя цель - просто запустить базовую программу RMI на AWS. Я займусь вопросами безопасности позже.

Запуск сервера - не проблема. И он правильно привязан к реестру RMI. Я использую следующую команду для его запуска:

java -Djava.security.manager -Djava.security.policy=C:\AWSTest\security.policy -Djava.rmi.server.codebase=file:/C:/AWS/Sources/sun-rmi-tutorial-server/bin/ file:/C:/AWS/Sources/sun-rmi-tutorial-common/bin/ -classpath C:\AWS\Sources\sun-rmi-tutorial-server\bin;C:\AWS\Sources\sun-rmi-tutorial-common\bin engine.ComputeEngine ec2-XX-XX-XX-XXX.ap-southeast-1.compute.amazonaws.com

  • Реестр RMI запускается на стороне сервера.
  • Я объявил новый менеджер безопасности на стороне сервера System.setSecurityManager(new RMISecurityManager())
  • Я использую security.policy файл, на который мне предоставлены все права.

Когда я запускаю клиентскую часть на моем локальном компьютере, я заканчиваю UnmarshalException:

ComputePi exception: error unmarshalling return; nested exception is: 
    java.lang.ClassNotFoundException: engine.ComputeEngine_Stub
java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
    java.lang.ClassNotFoundException: engine.ComputeEngine_Stub
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at java.rmi.Naming.lookup(Naming.java:101)
    at client.ComputePi.main(ComputePi.java:14)
Caused by: java.lang.ClassNotFoundException: engine.ComputeEngine_Stub
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:453)
    at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:184)
    at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:637)
    at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:264)
    at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:216)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1593)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    ... 3 more

Есть ли у вас какие-нибудь предложения относительно того, что не так? Почему клиент не может найти нужную заглушку? Я использую Eclipse Juno, плагин Genady RMI и Java 1.7.0_07.

Спасибо за вашу помощь

ИЗМЕНИТЬ 1:

Рабочее пространство Java организовано вокруг трех проектов: клиентской части, серверной части и общего проекта, в котором и сервер, и клиент совместно используют классы.

  • Я могу читать удаленный реестр со своего локального компьютера. Плагин RMI может удаленно подключаться к серверу и проверять реестр.

  • Если вместо создания трех проектов я поместил все классы в один проект, все будет работать нормально ... Но я заметил, что никаких заглушек не было создано (или необходимости).

  • Если на стороне клиента я помещаю ссылку в путь к классам на классы сервера (все создается локально), у меня возникает ошибка тайм-аута соединения вместо ошибки демаршаллинга.

    Исключение ComputePi: в соединении с хостом отказано: XX.XXX.XX.XX; вложенное исключение: java.net.ConnectException: время ожидания соединения истекло: соединение java.rmi.ConnectException: соединение с хостом отказано: XX.XXX.XXX; вложенное исключение: java.net.ConnectException: время ожидания соединения истекло: подключиться к sun.rmi.transport.tcp.TCPEndpoint.newSocket (TCPEndpoint.java:619) к sun.rmi.transport.tcp.TCPChannel.createConnection (TCPChannel.java : 216) в sun.rmi.transport.tcp.TCPChannel.newConnection (TCPChannel.java:202) на sun.rmi.server.UnicastRef.invoke (UnicastRef.java:128) в engine.ComputeEngine_Stub.executeTask (ComputeEngine_ 35) в client.ComputePi.main (ComputePi.java:19) Вызвано: java.net.ConnectException: время ожидания соединения истекло: подключитесь к java.net.DualStackPlainSocketImpl.connect0 (собственный метод) к java.net.DualStackPlainSocketImpl.socketConnect ( DualStackPlainSocketImpl.java:69) в java.net.AbstractPlainSocketImpl.doConnect (AbstractPlainSocketImpl.java:339) в java.net.AbstractPlainSocketImpl.connectToAddress (AbstractPlainSocketImpl.Implain.java. ) на java.net.PlainSocketImp l.connect (PlainSocketImpl.java:157) на java.net.SocksSocketImpl.connect (SocksSocketImpl.java:391) на java.net.Socket.connect (Socket.java:579) на java.net.Socket.connect (Socket .java: 528) на java.net.Socket. (Socket.java:425) на java.net.Socket. (Socket.java:208) на sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket (RMIDirectSocketFactory.java: 40) at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket (RMIMasterSocketFactory.java:146) at sun.rmi.transport.tcp.TCPEndpoint.newSocket (TCPEndpoint.java:613) ... Еще 5


person BlackLabrador    schedule 19.11.2012    source источник


Ответы (1)


Вы не развернули класс-заглушку для клиента.

person user207421    schedule 19.11.2012
comment
Спасибо за вашу помощь. Не могли бы вы быть более откровенными? Просто чтобы добавить точности к моей проблеме. Рабочее пространство Java организовано вокруг трех проектов: клиентской части, серверной части и общего проекта, в котором и сервер, и клиент совместно используют классы. - person BlackLabrador; 20.11.2012
comment
@BlackLabrador Я не могу согласиться с тем, что требуется дополнительная точность. Либо вы развернули свой класс-заглушку для клиента, либо нет, и вы этого не сделали. Это бинарное состояние. Очевидно, что класс-заглушка принадлежит совместно используемому JAR-файлу, и столь же очевидно, что его там нет. - person user207421; 20.11.2012
comment
Привет, спасибо, что ответили. То, что может быть очевидным для опытного программиста Java RMI, может быть не для новичка. Я не знаю, как развернуть программу RMI ... что может объяснить мои проблемы. было неочевидно, что на стороне клиента должен быть файл JAR сервера ... Я думал, что вся цель RMI - сделать его доступным для клиента через реестр. Если заглушка была экспортирована на стороне сервера, клиент должен ее найти. Когда я смотрю файл конфигурации, который поставляется с примером, я не вижу ссылки на серверный JAR в кодовой базе. Я добавил Edit 2 в свой комментарий - person BlackLabrador; 20.11.2012
comment
@BlackLabrador Вы уже догадались, что, по вашему мнению, неочевидно, что между клиентом и сервером должны быть общие классы. Вы просто не все правильно поняли. Сообщение об ошибке было достаточным, чтобы сказать вам об этом. - person user207421; 20.11.2012