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

Опитвам се да внедря урока за RMI Compute PI, намерен на уебсайта на Sun/Oracle тук. Сървърът се намира на Amazon windows EC2 Server. Клиентът се намира на личния ми компютър у дома. Само за да опростя нещата, деактивирах защитната стена на сървъра и отворих всички портове на групата за сигурност 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 Plugin и Java 1.7.0_07.

Благодаря за вашата помощ

РЕДАКТИРАНЕ 1:

Работното пространство на Java е организирано около 3 проекта: страна на клиента, страна на сървъра и общ проект, където и сървърът, и клиентът споделят класове.

  • Мога да чета отдалечения регистър от моя локален компютър. Приставката RMI може да се свърже дистанционно със сървъра и да инспектира системния регистър.

  • Ако вместо да направя 3 проекта, поставя всички класове под един и същи проект, всичко работи добре... Но забелязвам, че не са генерирани (или необходими) мъничета.

  • Ако от страна на клиента поставям препратка в classpath към сървърните класове (всичко се изгражда локално), имам грешка при изчакване на връзката вместо грешка при демаршалиране.

    Изключение на 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_Stub.java: 35) в client.ComputePi.main(ComputePi.java:19) Причинено от: java.net.ConnectException: Времето за изчакване на връзката изтече: свържете се в java.net.DualStackPlainSocketImpl.connect0(Native Method) в java.net.DualStackPlainSocketImpl.socketConnect( DualStackPlainSocketImpl.java:69) на java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339) на java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200) на java.net.AbstractPla inSocketImpl.connect(AbstractPlainSocketImpl.java:182 ) в java.net.PlainSocketImpl.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) в sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:146) в 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 е организирано около 3 проекта: страна на клиента, страна на сървъра и общ проект, където и сървърът, и клиентът споделят класове. - person BlackLabrador; 20.11.2012
comment
@BlackLabrador Не мога да се съглася, че е необходима допълнителна точност. Или сте разположили вашия клас мъниче на клиента, или не сте го направили и не сте го направили. Това е двоично състояние. Очевидно класът мъниче принадлежи към споделения JAR файл и също толкова очевидно не е там. - person user207421; 20.11.2012
comment
Здравейте, благодаря за отговора. Това, което може да е очевидно за опитен Java RMI програмист, може да не е за начинаещ. Не знам как да разположа RMI програма... което може да обясни проблемите ми. не беше очевидно, че клиентската страна трябва да включи JAR файла на сървъра... Мислех, че цялата цел на RMI е да направи това достъпно за клиента чрез регистъра. Докато мъничето е експортирано от страната на сървъра, клиентът трябва да го намери. Когато гледам конфигурационния файл, който идва с примера, не виждам никаква препратка към JAR на сървъра в кодовата база. Добавих Редактиране 2 в моя коментар - person BlackLabrador; 20.11.2012
comment
@BlackLabrador Вече беше разбрал това, което сега твърдиш, че не е очевидно, че трябва да има някои общи класове между клиент и сървър. Просто не си ги разбрал добре. Съобщението за грешка беше достатъчно, за да ви каже това. - person user207421; 20.11.2012