Как установить путь к классам, который использует rmiregistry?
Я пытаюсь создать клиентское/серверное приложение Java RMI. У меня возникают проблемы с запуском серверной части моего приложения, так как он продолжает работать в ClassNotFoundException во время вызова метода Registry.bind(), когда я пытаюсь запустить серверную часть приложения.
Я начал с простого учебника здесь: http://docs.oracle.com/javase/1.5.0/docs/guide/rmi/hello/hello-world.html. После выполнения этих инструкций изначально было выбрано ClassNotFoundException, жалуясь, что он не смог найти "example.hello.Hello". Я смог решить это, запустив rmiregistry из каталога destDir в учебнике, так как rmiregistry, по-видимому, использует свой начальный каталог запуска как часть своего пути к классам.
После этого я начал работу с другим тестовым приложением, и все было в порядке, пока я не начал использовать сторонние файлы jar в своем классе сервера. Теперь Registry.bind() выдает исключение ClassNotFoundException, если мой класс сервера ссылается на что-либо в любом файле jar, поскольку приложение rmiregistry не знает об этих файлах jar.
Насколько я могу судить, rmiregistry не принимает какой-либо атрибут startpath для classpath, поэтому мне интересно, как я могу сказать, какой classpath я хочу, чтобы он признал. В соответствии с инструкцией здесь: http://docs.oracle.com/javase/tutorial/rmi/running.html, "вы должны убедиться, что оболочка или окно, в котором вы будете запускать rmiregistry, имеют no CLASSPATH, или имеет переменную среды CLASSPATH, которая не включает путь к любым классам, которые вы хотите загрузить клиентам ваших удаленных объектов." Это звучит как противоположность тому, что мне нужно... или я читаю его неправильно? Кто-нибудь успел запустить клиент/сервер RMI, который использует сторонние банки (commons-io, commons-logging и rmiio, в моем случае)?
Это в Windows, по-своему.
Обновление
Я нашел способ обойти это. См. Мой ответ ниже.
Ответы
Ответ 1
(Я изначально опубликовал этот ответ в качестве обновления к моему вопросу. В одном из комментариев по предложению Zecas я перехожу к разделу ответа.)
Мне удалось запустить часть сервера, не подчиняясь предложению во втором учебнике, упомянутом в моем вопросе выше:
"вы должны убедиться, что оболочка или окно, в котором вы будете запускать rmiregistry либо имеет не CLASSSPATH переменную окружения или имеет переменную среды CLASSPATH, которая не включает путь к любые классы, которые вы хотите загрузить клиентам вашего удаленного объекты".
Я создал переменную среды CLASSPATH и добавил к этому свой выходной каталог .class и каждый из сторонних файлов jar. Я думал, что раньше я это пробовал, но, наверное, не... Просто подумал, что оставлю свое решение, если у кого-то другая проблема.
Ответ 2
Замечания об отключении CLASSPATH применяются только в том случае, если вы используете функцию кодовой базы RMI, поскольку подразумевается загадочное замечание о загрузке классов.
Если вы не используете функцию codebase, просто:
- Задайте переменную среды CLASSPATH, как требуется, перед запуском
rmiregistry,
, как показано здесь в другом месте, или
- Запустите
rmiregistry
с помощью -J-Djava.class.path=...
- Запустите Реестр внутри вашего JVM сервера,
LocateRegistry.createRegistry().
Это во многих отношениях лучшее решение, так как оно живет и умирает с JVM, разделяет его путь к классам и, кстати, соответствует требованиям для функции codebase.
Если вы это сделаете (3), вы должны сохранить возвращаемое значение в статическую переменную, чтобы предотвратить его сбор мусора, что приводит к тому, что реестр будет неэкспортирован, что может привести к дублированию удаленного объекта, что может привести к к нему будет GC'd, что приведет к выходу слушающего потока, что может привести к выходу всего JVM.
Ответ 3
Не существует определенного пути класса java для реестра. Он должен использовать тот же путь класса, что и остальная часть системы Java. Вы можете установить свой путь к классам, указав его в командной строке или в вашей ОС. Хотя это doc, должно указывать на вас в правильном направлении.
Ответ 4
Пример того, как установить classpath для rmiregistry
Win32:
set CLASSPATH=c:\home\ann\src;c:\home\ann\public_html\classes\compute.jar
UNIX:
setenv CLASSPATH /home/ann/src:/home/ann/public_html/classes/compute.jar