Почему клиент RMI должен иметь заглушку в своем пути к классам? - PullRequest
2 голосов
/ 12 марта 2012

Примечание: я изменил название вопроса, чтобы быть более точным

Вот мой вопрос: при использовании RMI для связи между клиентом и сервером клиенту нужно иметь Stub в своем пути к классам, или Stub должен быть только на на стороне сервера?

<ч /> Обратите внимание, «полная» история:

В настоящее время я работаю над веб-приложением, которое вызывает механизм расчета. Связь между этими двумя элементами осуществляется с помощью RMI .

Вот Maven структура проекта:

my-project
 +- core
 +- web-application
 +- engine

И web-application, и engine зависят от core.

В модуле core я определил интерфейс:

public interface MyEngine extends java.rmi.Remote {

    MyResults calculate() throws RemoteException;

}

В модуле engine (который является сервером с точки зрения RMI), я определяю реализацию этого интерфейса:

public class MyEngineImpl extends UnicastRemoteObject implements MyEngine {

    public MyResults calculate() throws RemoteException {
        ...
    }

    public static void main(String... args) {
        MyEngine engine = new MyEngineImpl();
        Registry registry = LocateRegistry.createRegistry(1418);
        registry.rebind("my-engine", engine);
    }

}

Наконец, на web-application я написал класс, который вызывает модуль двигателя, используя интерфейс core:

public class RemoteEngineFacade {

    public MyResults callCalculate() throws RemoteException {
        Registry localisation = LocateRegistry.getRegistry("url-of-engine", 1418);
        MyEngine engine = (LiquidityEngine) localisation.lookup("my-engine");
        return engine.calculate();
    }

}

Компиляция RMI выполняется с помощью плагина rmic Maven:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>rmic-maven-plugin</artifactId>
    <version>1.1</version>
    <executions>
        <execution>
            <id>rmi compilation</id>
            <goals>
                <goal>rmic</goal>
            </goals>
            <configuration>
                <outputDirectory>target/classes</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

(обратите внимание, что это определение подключаемого модуля выполнено для каждого модуля)

Теперь, после развертывания приложения, когда web-application вызывает engine, я получаю следующую ошибку в журналах веб-приложения :

2012-03-12 09:42:37 ERROR [xxx.RemoteEngineFacade] Engine is unable to respond to the request
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
    java.lang.ClassNotFoundException: xxx.MyEngineImpl_Stub (no security manager: RMI class loader disabled)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at xxx.RemoteEngineFacade.callCalculate(RemoteEngineFacade.java:50)
    ...

Я не понимаю, почему он ищет заглушку на стороне web-application, так как обычно заглушка должна быть расположена только на сервере RMI (engine в моем контексте).

У вас есть идеи, где моя проблема?

Спасибо.

<Ч />

Редактировать : Настройка диспетчера безопасности, как объяснено в Riddhish.Chaudhari, ответ действительно решил проблему. Единственное отличие состоит в том, что у меня нет без менеджера безопасности: загрузчик классов RMI отключен сообщение в трассировке стека ...

<Ч />

Редактировать 2 : Если я скопирую файл engine.jar в мой WEB-INF/lib, то связь будет выполнена правильно. Но мне не нужно было добавлять библиотеку движка в мое веб-приложение ...

Ответы [ 2 ]

2 голосов
/ 12 марта 2012

Я наконец решил свою проблему. На этой странице сказано, что

Начиная с выпуска J2SE 5.0, классы-заглушки для удаленных объектов больше не нужно предварительно создавать с помощью компилятора заглушки rmic, если только удаленныйобъект должен поддерживать клиентов, работающих на виртуальных машинах до 5.0

Поскольку я работаю с Java 6, я решил просто удалить задачи rmic из моих файлов pom.xml... и это сработало!

Возможно, наличие Stub на сервере (мой движок) создает некоторую путаницу для JVM, которая выдает ошибку, которую я получил ...

0 голосов
/ 12 марта 2012

Вы не используете менеджер безопасности:

Есть ли у вас файл политики (mypolicy.policy):

grant {
  permission java.security.AllPermission;
};

и запустите вашу программу, используя

java -Djava.security.manager -Djava.security.policy=/some/path/myplicy.policy MyClass

Используйте приведенную ниже ссылку для полного примера использования разрешения политики безопасности

http://www.javacoffeebreak.com/articles/javarmi/javarmi.html

...