Добрый день, коллеги.
Попробовал создать простенькое программное обеспечение для обучения работе с RMI, и наткнулся на проблему ошибки java.io.EOFException, выдаваемой серверной или клиентской частью, если они запущены не из под NetBeans а с помощью ключей java. То есть, например, созданный архив .jar при запуске отдельно от среды (java -jar) выдает эту ошибку при считывании информации с экспортированного объекта RMI, а под средой все прекрасно, как написано в руководстве и на сайте Oracle в примерах. Перерыл весь интернет, даже переведенный с китайского статьи читал, везде эту ошибку знают, но ни одного стоящего решения не предлагается. Сразу: указание classpath в любом месте пробовал, не помогает, ключи java -D... известные мне тоже ситуацию не исправили. Внесение системной переменной CLASSPATH тоже оказалось бесполезным. Может, кто знает, как правильно указать ключи какие-нибудь при компилляции или запуске, или прописать что-то куда-то, чтобы заработало? Думал бы, что это системный баг RMI в java, но в NetBeans это ведь работает! Еще: никакого отношения не имеет к ошибке ClassNotFound создаваемого с помощью rmic файла _Stub, в этом я разобрался, просто похоже внешне.
Участок кода моей программы с серверной ее частью, куда от удивления вставил блок самопроверки со считыванием выгруженных данных, после чего в NetBeans все работает, отдельно, как ни запускай — ошибка:
//............................
//задание имени удаленного объекта
String serverObjectName = "WeatherService";
//порт по умолчанию для RMI
final int remotePort = 1099;
final String remoteHost = "localhost";
//контрольный вывод полученного содержимого о погоде
java.util.List<WeatherBean> list =
service.getWeatherInformation();
for (int i = 0; i < list.size(); i++) {
//поиск удаленного объекта WeatherService
Remote remote = registry.lookup(serverObjectName);
/*
//работает, даже если убрать этот комментарий и
//использовать прямое преобразование вместо Proxy
WeatherService weatherService = (WeatherService)
registry.lookup(serverObjectName);
*/
if (Proxy.isProxyClass(remote.getClass())) {
//получение proxy вместо прямого преобразования
Proxy proxy = (Proxy) remote;
//тут надо еще и вызвать специальный указатель
InvocationHandler invocationHandler =
Proxy.getInvocationHandler(proxy);
//преобразование к виду Remote из Proxy в связи с
//изменениями в v.6
WeatherService weatherService = (WeatherService)
Proxy.newProxyInstance(
WeatherService.class.getClassLoader(),
new Class[] { WeatherService.class },
invocationHandler);
//прверка содержимого созданного удаленного объекта
service.addTextWeatherString(
"Проверка содержимого удаленного объекта " +
"WeatherService:");
service.showEvent("Получение удаленной информации");
list = weatherService.getWeatherInformation();
service.showEvent("Вывод содержимого удаленного объекта");
for (int i = 0; i < list.size(); i++) {
service.showEvent("WeatherService успешно запущен");
//............................
Текст ошибки, выдаваемой вне среды NetBeans, выглядит следующим образом:
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.io.EOFException
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:173)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132)
at $Proxy0.getWeatherInformation(Unknown Source)
at deitel.rmi.weather.server.WeatherServiceImpl.main(WeatherServiceImpl.java:308)
Caused by: java.io.EOFException
at java.io.DataInputStream.readInt(DataInputStream.java:375)
at java.io.ObjectInputStream$BlockDataInputStream.readInt(ObjectInputStream.java:2775)
at java.io.ObjectInputStream.readInt(ObjectInputStream.java:949)
at javax.swing.ImageIcon.readObject(ImageIcon.java:441)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at java.util.ArrayList.readObject(ArrayList.java:593)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:155)
... 4 more