2013-10-26 4 views
0

Я пытаюсь настроить приложение RMI, которое когда-то работало, но теперь я получаю странное поведение. Когда я запускаю его без Окурка я получаю java.lang.ClassNotFoundException: HelloInterface Затем я добавляю новый файл (Hello_Stub) в каталог (используя РЦМП), , а затем я получаю java.lang.ClassNotFoundException: Hello_Stub* Добавление * файл вызывает java.lang.ClassNotFoundException на сервере RMI

WTF ?? Он не жаловался на недостаток Hello_Stub, когда он отсутствовал; но когда я добавляю этот файл, он начинает жаловаться, что он НЕ существует. А?

Что находится внизу транскрипта с терминала. Сначала вы видите одну ошибку; затем я перечисляю файлы в текущем каталоге; затем я создаю файл Stub и покажу вам это; то вы увидите сообщение об ошибке, где он жалуется, что файл просто добавил отсутствует:

[email protected]:/kearnsgroup/www/RMItest/classes> java HelloServer 
initializing Hello class: Hello, world! 
Hello Server failed: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: HelloInterface 


[email protected]:/kearnsgroup/www/RMItest/classes> ll 
total 32 
-rw------- 1 sjudd sjudd 765 Oct 25 19:52 Hello.class 
-rw------- 1 sjudd sjudd 967 Oct 25 19:52 HelloClient.class 
-rw-r----- 1 sjudd sjudd 614 Oct 25 19:42 HelloClient.java 
-rw------- 1 sjudd sjudd 222 Oct 25 19:52 HelloInterface.class 
-rw-r----- 1 sjudd sjudd 360 Oct 25 09:08 HelloInterface.java 
-rw-r----- 1 sjudd sjudd 847 Oct 25 09:56 Hello.java 
-rw------- 1 sjudd sjudd 916 Oct 25 19:52 HelloServer.class 
-rw-r----- 1 sjudd sjudd 439 Oct 25 09:14 HelloServer.java 


[email protected]:/kearnsgroup/www/RMItest/classes> rmic Hello 
[email protected]:/kearnsgroup/www/RMItest/classes> ll 
total 36 
-rw------- 1 sjudd sjudd 765 Oct 25 19:52 Hello.class 
-rw------- 1 sjudd sjudd 967 Oct 25 19:52 HelloClient.class 
-rw-r----- 1 sjudd sjudd 614 Oct 25 19:42 HelloClient.java 
-rw------- 1 sjudd sjudd 222 Oct 25 19:52 HelloInterface.class 
-rw-r----- 1 sjudd sjudd 360 Oct 25 09:08 HelloInterface.java 
-rw-r----- 1 sjudd sjudd 847 Oct 25 09:56 Hello.java 
-rw------- 1 sjudd sjudd 916 Oct 25 19:52 HelloServer.class 
-rw-r----- 1 sjudd sjudd 439 Oct 25 09:14 HelloServer.java 
-rw------- 1 sjudd sjudd 1635 Oct 25 20:34 Hello_Stub.class 


[email protected]:/kearnsgroup/www/RMItest/classes> java HelloServer 
initializing Hello class: Hello, world! 
Hello Server failed: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: Hello_Stub 

Обратите внимание, что то, что не удается здесь является сервер RMI, а не клиент.

Этот код отлично работает на одной машине (Mac), но при копировании на другой (Linux) он вызывает эту удивительную ошибку.

Я так потрясен этой странностью, я не знаю, как подойти к ней. Может ли это иметь какое-то отношение к шагу отмены? или с переменными среды? Возможно, CLASSPATH? Я не вижу, что искать. Любые дикие теории?

+0

Есть ли в Linux-машине ваши классы в classpath? –

ответ

0

Не добавляйте заглушку. Вы не нуждаетесь в нем с Java 1.5. Просто убедитесь, что вы соблюдаете требования, изложенные в преамбуле к Javadoc, для UnicastRemoteObject.. Исходная проблема вызвана тем, что класс удаленного интерфейса не доступен в CLASSPATH для реестра или клиента или для обоих.

+0

Большое спасибо. Вы положили пальцем на проблему. Различные учебники по RMI все говорят, чтобы начать rmiregistry, но те, на которых я полагался, подробно остановились на том, где это сделать. Rmiregistry неизменно начинается без жалобы, и проблема не очевидна, пока вы не попытаетесь запустить сервер. В этот момент нет намека на исключения, которые они вызвали из-за чего-то в другом процессе! –

+0

Тем не менее, головоломка выше все еще стоит как совершенно непонятное поведение. Да, я согрешил, начав rmiregistry в неправильном месте, но симптомом, который он в конечном итоге вызывает, является для загрузчика не найти класс, который я только что поставил на его пути. Он явно реагирует на то, что соответствующий класс присутствует, и утверждая, что он не существует в то же время! Это совершенно непонятно - даже сейчас, когда я знаю, как этого избежать.Конечно, что-то может дать более полезное сообщение, чем то, которое нам дано. –

+0

(a) На самом деле есть подсказка: «Исключение сервера» в трассировке стека. (b) Если вы создаете заглушку, серверу требуется его при экспорте; Регистр нуждается в нем, когда вы связываете; и клиенту это нужно при поиске. То же самое относится к самому удаленному интерфейсу и всем классам приложений, от которых он зависит, и т. Д. Рекурсивно до закрытия. – EJP

0

Я начал rmiregistry, не обращая внимания на его путь к классу. С помощью cd'ing в каталог классов и начиная с него все проблемы исчезли.

Я считаю, что вы можете сделать то же самое с флагами, которые определяют CLASSPATH или кодовую базу для программы rmiregistry. Кто-нибудь знает синтаксис? Я попробовал это (безуспешно):

rmiregistry -JCLASSPATH = "путь/к/классов /"
rmiregistry -JCLASSPATH = "/ абсолютный/путь/к/классов /"
rmiregistry -J-DCLASSPATH = "путь/в/классы /»
rmiregistry -J-DCLASSPATH = "/ абсолютный/путь/к/классов /"

все они вызывают java.lang.ClassNotFoundException: BNS.plumbing.SessionHostInterface , когда сервер начнет работать. (Это поведение, по крайней мере.)

+0

Параметр '-classpath' является параметром командной строки (а не свойство) для команды' java', и для этого требуется отдельный аргумент. Чтобы передать такие аргументы через 'java' из' rmiregistry', сделайте что-то вроде: 'rmiregistry -J-classpath -Jpath/to/your/classes'. –

Смежные вопросы