RMI с включением нескольких JAR - PullRequest
1 голос
/ 02 сентября 2011

Я кодирую программу RMI с 3 JAR:

  • RMIServer, содержит классы на стороне сервера
  • RMIClient содержит классы на стороне клиента
  • RMIResource содержит серверобщий контент & клиент (интерфейсы, пользовательские исключения)

Чтобы создать отдельные файлы JAR, я создал 3 проекта в NetBeans, а затем объявил общий Jar в разделе «Библиотеки / сборка» других 2проекты.

Все просто наладилось, ошибок нет.

Но когда я пытаюсь запустить сервер через командную строку, что было несложно до того, как у меня появилась идея поместить общий ресурсфайлов в отдельном JAR, это внезапно становится болью в a ** ...

Вот несколько примеров команд, которые я пробовал:

  • Сохранение указателя ClassPathк ресурсам сервера, но с использованием двойной CodeBase

    java -cp ~/NetBeansProjects/RMIServer/dist/RMIServer.jar -Djava.rmi.server.codebase="file:/home/myuser/netbeansprojects/rmiserver/dist/rmiserver.jar file:/home/myuser/netbeansprojects/rmiserver/dist/lib/rmiresource.jar" rmiserver.Shop
    

Результат:

Network exception: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
java.lang.ClassNotFoundException: rmiresource.BookingManager
...
  • Использование двойной ClassPath с сохранением CodeBase, указывающим наресурсы сервера

    java -cp "~/NetBeansProjects/RMIServer/dist/RMIServer.jar;~/NetBeansProjects/RMIServer/dist/lib/RMIResource.jar" -Djava.rmi.server.codebase=file:/home/myuser/netbeansprojects/rmiserver/dist/rmiserver.jar rmiserver.Shop
    

Результат:

Exception in thread "main" java.lang.NoClassDefFoundError: rmiserver/Shop
Caused by: java.lang.ClassNotFoundException: rmiserver.Shop
...
  • Использование двойной ClassPath и двойной CodeBase

    java -cp "~/NetBeansProjects/RMIServer/dist/RMIServer.jar;~/NetBeansProjects/RMIServer/dist/lib/RMIResource.jar" -Djava.rmi.server.codebase="file:/home/myuser/netbeansprojects/rmiserver/dist/rmiserver.jar file:/home/myuser/netbeansprojects/rmiserver/dist/lib/rmiresource.jar" rmiserver.Shop
    

Результат:

Exception in thread "main" java.lang.NoClassDefFoundError: rmiserver/Shop
Caused by: java.lang.ClassNotFoundException: rmiserver.Shop
...

РЕДАКТИРОВАТЬ: я работаю на локальном компьютере, имитируя удаленные соединения.Таким образом, я использую протокол «file», а не «http».

Я что-то упустил?Спасибо за любую помощь, которую вы бы оказали


Я снова проверил свое 1-е решение, так как оно было самым многообещающим:

    java -cp ~/NetBeansProjects/RMIServer/dist/RMIServer.jar -Djava.rmi.server.codebase="file:/home/myuser/netbeansprojects/rmiserver/dist/rmiserver.jar file:/home/myuser/netbeansprojects/rmiserver/dist/lib/rmiresource.jar" rmiserver.Shop

Оно все равно не удалось.

ТогдаЯ проверил на Windows:

  1. Установите rmiregistry с пустым classpath (и перейдите в каталог java / bin)

    set CLASSPATH=""; export CLASSPATH
    start rmiregistry
    
  2. Запустите сервер с такой же командой, как и раньше (по модулю изменений Win env)

    java -cp c:/NetBeansProjects/RMIServer/dist/RMIServer.jar -Djava.rmi.server.codebase="file:/c:/netbeansprojects/rmiserver/dist/rmiserver.jar file:/c:/netbeansprojects/rmiserver/dist/lib/rmiresource.jar" rmiserver.Shop
    

И ... Это сработало!

Я вычистил / перестроилрешение для Linux и Windows, и оно все еще не работает на Linux и работает на Windows ... Я использую одну и ту же версию Netbeans на обоих!

Может кто-нибудь объяснить это мне?Я использую JDK 6 в Linux и JDK 7 в Windows: это повлияет?

1 Ответ

0 голосов
/ 02 сентября 2011

Файл: кодовая база не может работать с локальной машины.Вам нужно использовать HTTP.Вы могли бы использовать файл: URL, указывающий на общий каталог, так что URL имеет смысл на клиенте, но это не будет работать за пределами локальной сети.

Если вы не используете функцию кодовой базы, RMIРеестру необходим доступ к общим классам через его classpath: rmiregistry -J-Dclasspath = ... Проще использовать LocateRegistry.createRegistry (), тогда он находится в той же JVM, что и ваши удаленные объекты, и, конечно, использует тот же путь к классам.

...