It shouldn't be this wicked. Ok, I admit it has been a while since I implemented a Java RMI based client/server. But, it shouldn't be this wicked. So, I was trying to get some RMI client/server code running on my machine. And I kept getting was this friggin exception:

Caused by: javax.naming.CommunicationException [Root exception is java.rmi.ServerException: 
RemoteException occurred in server thread; 
nested exception is: java.rmi.UnmarshalException: error unmarshalling arguments; 
nested exception is: java.lang.ClassNotFoundException: com.sun.salsa.PatternModelImpl_Stub

The RMI docs said that anytime you get a ClassNotFoundException, it is most likely caused by an improperly set codebase[J] So I checked the value of my java.rmi.server.CodeBase property. It was set as follows:

java.rmi.server.CodeBase=file://dev/salsa/classes 

I checked to make sure that the directory was there and that all the stubs and other classes were in there. They were. So, I ran the RMI server program again. But, again I got the same exception. What the heck is going on? And then it hit me. Isn't that supposed to be codebase and not CodeBase?

So I change "CodeBase" to "codebase" and reset the property as follows:

java.rmi.server.codebase=file://dev/salsa/classes 

And give the program another try. This time, I got a different exception.

Exception in thread "main" java.security.AccessControlException:    
access denied (java.io.FilePermission //dev/salsa/classes read)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
at java.security.AccessController.checkPermission(AccessController.java:427)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at java.lang.SecurityManager.checkRead(SecurityManager.java:871)
... 

Hmm...this looks like we need some permissions granted. That's easy, let me go the $JRE/lib/security directory and change the java.policy file and add a new grant permission and it should all be fine. So I edit the java.policy file and add the grant permission:

grant codeBase "file://dev/salsa/classes" {
permission java.io.FilePermission "<<ALL FILES>>", "read";
};

I run the program thinking I fixed the problem for good. But not so fast! I see the same exception again. Then it hit me again. I had committed another silly error. It appears that I gave 2 slashes (file://...) to the codebase to separate the protocol and the url.

So I quickly undo the changes I made to the java.policy file. I go back to the codebase property and this time I set it as follows:

java.rmi.server.codebase=file:/dev/salsa/classes

I restart my RMI server and voila! Everything works fine this time!

Thought this record of my silly errors might help someone else sometime.

[J] Thanks to Jeremy Pitten for reminding me the codebase settings.

YouRIt
Comments:

Standard advice for RMi newbies is DON'T try to use file URLs. They are hard to get right. SPin upa simple web server and start with that.

You can't really blame RMI for this-- the syntax for file URLs was messed up by the W3C

Posted by 192.18.37.43 on April 20, 2005 at 10:11 AM PDT #

Actually, don't just start with a non-file URL. Don't -ever- use a file: URL. What happens is that you get your system working on your local machine, then wonder why it doesn't work when the client is a different machine on the network (which obviously won't have access to the file system on the service node).

Just get the web server set up and deal with the codebase properly. You're going to have to do it eventually.

Also, you should really just bite the bullet and use Jini.

Posted by Greg Trasuk on April 20, 2005 at 03:08 PM PDT #

Here's a dumb question: why doesn't the file: url have <em>three</em> slashes? As in <code>file:///dev/salsa/classes</code> since the scheme of a uri always starts with <code>name://</code> and the root directory is <code>/</code> on unix.

Posted by Jimmy Cerra on April 20, 2005 at 10:33 PM PDT #

Post a Comment:
Comments are closed for this entry.

This blog copyright 2007 by alur