Note: I changed the question title to be more precise
Here is my question: When using RMI to communicate between a client and a server, does the client needs to have the Stub
in his classpath, or does this Stub
should only be on server side?
Note, the "full" story:
I am currently working on a web-application that calls a calculation engine. The communication between these 2 elements is made using RMI.
Here is Maven structure of the project:
my-project
+- core
+- web-application
+- engine
Both web-application
and engine
have a dependency on core
.
In core
module, I've defined an interface:
public interface MyEngine extends java.rmi.Remote {
MyResults calculate() throws RemoteException;
}
In engine
module (which is the server on the RMI point of view), I define the implementation of this interface:
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);
}
}
Finally, on the web-application
, I wrote a class that calls the engine module, using the interface of 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();
}
}
The RMI compilation is made by the rmic
Maven plugin:
<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>
(note that this plugin definition is made on each module)
Now, after deploying the application, when the web-application
is calling the engine
, I get the following error on the web-application logs:
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)
...
I don't get why it is looking for the Stub on the web-application
side, as normally the Stub has only to be located on the RMI server (the engine
in my context).
Do you have any idea where is my problem?
Thanks.
Edit: Setting a security manager, as explained in Riddhish.Chaudhari answer did solve the issue. The only difference is that I don't have the no security manager: RMI class loader disabled message in the stacktrace anymore...
Edit 2: If I copy the engine.jar in my WEB-INF/lib
, then the communication is made correctly. But I should not have to add the engine library in my web-application...