java.rmi.server.codebase clarification

D

david

Hello Guys,

I have developed a distributed Server and client application using
RMI.
First I tested both by running those in the same machine. It worked
fine.
But when I tried to keep the server classes(and stubs) in one machine
and the client classes in another machine, and test it, I got the
following exception.

Exception at the client side,
------------<Exception starts here>--------------------------------
Client exception: java.rmi.UnmarshalException: error unmarshalling
return; nested exception is:
java.lang.ClassNotFoundException: MyRMIServer_Stub
java.rmi.UnmarshalException: error unmarshalling return; nested
exception is:
java.lang.ClassNotFoundException: MyRMIServer_Stub
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at Client.<init>(Client.java:71)
at Client.main(Client.java:165)
Caused by: java.lang.ClassNotFoundException: MyRMIServer_Stub
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:
320)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:
434)
at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:
165)
at java.rmi.server.RMIClassLoader$2.loadClass
(RMIClassLoader.java:620)
at java.rmi.server.RMIClassLoader.loadClass
(RMIClassLoader.java:247)
at sun.rmi.server.MarshalInputStream.resolveClass
(MarshalInputStream.java:197)
at java.io_ObjectInputStream.readNonProxyDesc
(ObjectInputStream.java:1575)
at java.io_ObjectInputStream.readClassDesc
(ObjectInputStream.java:1496)
at java.io_ObjectInputStream.readOrdinaryObject
(ObjectInputStream.java:1732)
at java.io_ObjectInputStream.readObject0
(ObjectInputStream.java:1329)
at java.io_ObjectInputStream.readObject(ObjectInputStream.java:
351)
..
..
..
------------<Exception ends here>--------------------------------


I will give my server and client implementation details.

In server, I do the following

---->Server side code<-----
Server()
{
if (System.getSecurityManager() == null)
System.setSecurityManager ( new
RMISecurityManager() );

stub = (MyRMIInterface) UnicastRemoteObject.exportObject(myRMIServer,
0);
registry = LocateRegistry.getRegistry(host,port); //host is the IP
address passed, port 1099 by default
registry.bind("TestingRMIServer", stub);
}//server

---->Server side code<-----
Server IP address:192.168.2.181

user@server$echo $CLASSPATH
/home/user/server
user@server$rmiregistry & //
runs at the default port
user@server$java -Djava.security.manager -
Djava.security.policy=sec.policy -Djava.rmi.server.codebase=file:///
home/user/ Server 192.168.2.181

user@server$java -version
java version "1.6.0_12"
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) Server VM (build 11.2-b01, mixed mode)


--------------------------------------------------------------------------------------------------------------------------------
In the client side, I implemented the following,

--->Client Side<----
Client
{
if (System.getSecurityManager() == null)
System.setSecurityManager ( new RMISecurityManager() );

registry = LocateRegistry.getRegistry
(host,port); //the rmiregistry's IP address, and
the port
stub = (MyRMIInterface) registry.lookup("TestingRMIServer");
}//client

---->Client side<----

the client's IP address is :192.168.2.185
===<Client>=====
user@myclient$echo $CLASSPATH
/home/user/client
user@myclient$ java -Djava.security.manager -
Djava.security.policy=sec.policy -Djava.rmi.server.codebase=file:///
home/user/ Client 192.168.2.181 1099

user@myclient$java -version //CLIENT SIDE JAVA
VERSION
java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) Client VM (build 11.0-b15, mixed mode, sharing)
==<Client>=====

The sec.policy file has the following and I use the same on both
client and server sides..
---->sec.policy<----
grant{
permission java.security.AllPermission;
};
---->sec.policy<----



I expected the client to (locate and)download the server's stub.
But I still could not figure out why there is an exception, even after
I used the RMI security manager, passed the security policy and set
the codebase.
I feel that it should be either to do with my codebase setting(I am
not sure whether I am setting the codebase both at the server and
client. ) or to do with the JVM version (Since the JVMs at the server
and client are different versions)

i)When I set the codebase at the server side in the command line, can
I specify the -Djava.rmi.server.codebase=file:///home/user/
even though, my server stub is present in /home/user/server/ ??

ii) When I invoke the client, am I setting the codebase right, by
doing -Djava.rmi.server.codebase=file:///home/user/
iii) Should I include the IP address of the rmiregistry also as part
of the code base setting at the client side??


These server and client programs worked perfectly fine when I kept
both at the same machine and set the class path accordingly. The
machines involved are all Linux machines.

Any kind of help is appreciated. Thanks.

--david
 
E

EJP

david said:
But when I tried to keep the server classes(and stubs) in one machine
and the client classes in another machine, and test it, I got the
following exception.

---->Server side code<-----

user@server$java -Djava.security.manager -
Djava.security.policy=sec.policy -Djava.rmi.server.codebase=file:///
home/user/ Server 192.168.2.181

As the client is in a different machine, how exactly is it going to
access file:///home/user in the server machine?

You have to define a codebase that the client will understand. Usually
that means an HTTP service. If you use a file: URL it would need to be a
shared drive, and specified in the way the client has to use it (not the
server's view).
i)When I set the codebase at the server side in the command line, can
I specify the -Djava.rmi.server.codebase=file:///home/user/
even though, my server stub is present in /home/user/server/ ??

The codebase is like a classpath; it is a list of places that are roots
of package systems, or JARs that contain package systems. If the server
classes are in package 'server' then the codebase should point to a JAR
or directory that contains 'server'.
ii) When I invoke the client, am I setting the codebase right, by
doing -Djava.rmi.server.codebase=file:///home/user/

When you invoke the client you shouldn't set the codebase at all. It has
no effect. The codebase comes from the server as an annotation on the
classes.

Another common problem with codebase is 'losing' the annotation in the
Registry. If the Registry is a separate process, it should *not* have
the classes concerned on its CLASSPATH - it should acquire them via the
codebase mechanism. Otherwise the annotation will be lost and the client
will get CNF exceptions.
iii) Should I include the IP address of the rmiregistry also as part
of the code base setting at the client side??

The registry's IP address has nothing to do with the codebase, and in
any case there is no such thing as 'the codebase setting at the client
side'.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top