• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Java RMI and MyEclipse

 
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I hope that someone else has already done the suffering to learn how to do this.

I am starting to experiment with writing Java RMI client and server code. I started with the Oracle demo where the client makes a request for the value of pi to an arbitrary number of places, and the server computes it and passes it back to the client.

I was able to get this working using javac and jar from the command line (which involves bundling the class files into a JAR, copying it over to the tomcat webapps directory). My guess is that there is some way to set this up in MyEclipse so that it compiles and redeploys--but it is not exactly obvious how to set this up. Help!

I am using MyEclipse 9.1, Tomcat 5.0.28 (please don't laugh; we're working on moving into modern times, and getting rid of our papyrus and clay tablets).

To simplify figuring out what is broken, I have taken the Oracle tutorial code and put in a single project, divided into three packages: client, compute, and engine. I can start the server (engine) with the following DOS batch file:



I can run the client side from the command line with the following DOS batch file:



where %1% is the parameter passed to the batch file specifying the number of digits of pi to have the server side calculate and return.


Then I tried to get MyEclipse to start the server in pretty much the equivalent way using the Run Configurations...:

Main.class: engine.ComputeEngine
Classpath: default classpath and c:\tomcat5\webapps\rmi\compute.jar
Environment: java.rmi.server.codebase=file:/c:\tomcat5\webapps\rmi\compute.jar
java.security.policy=server.policy

Code:
ComputeEngine exception:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: compute.Compute
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:385)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:240)
at sun.rmi.transport.Transport$1.run(Transport.java:153)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
at java.lang.Thread.run(Thread.java:595)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:343)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at engine.ComputeEngine.main(ComputeEngine.java:29)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: compute.Compute
at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:375)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:240)
at sun.rmi.transport.Transport$1.run(Transport.java:153)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:149)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
at java.lang.Thread.run(Thread.java:595)
Caused by: java.lang.ClassNotFoundException: compute.Compute
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:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:242)
at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:707)
at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:651)
at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:588)
at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:628)
at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:294)
at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:238)
at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1494)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1457)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1693)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1299)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:339)
... 9 more


As you can see, there is a ClassNotFoundException: compute.Compute

I'm hard pressed to see why. If I do a jar -tf c:\tomcat5\webapps\rmi\compute.jar I get:




Any suggestions?
 
Bartender
Posts: 4116
72
Mac TypeScript Chrome Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why are you deploying this to Tomcat as this has no web content at all? Can't you just bring the RMI server up standalone?
 
Clayton Cramer
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I thought that the Java RMI required a server to be running. It doesn't? The server side of this example is sufficient by itself?

That's actually quite neat, but does not answer the question of why I can't get this work from MyEclipse.
 
Clayton Cramer
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks! Indeed, it does not require Tomcat to be running to work. This is very neat. It still doesn't answer the question of why I can't get this to start from MyEclipse, but any time that I can reduce the number of components required to make something do what it needs, that's a gain.
 
Saloon Keeper
Posts: 27752
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Clayton Cramer wrote:I thought that the Java RMI required a server to be running. It doesn't? The server side of this example is sufficient by itself?

That's actually quite neat, but does not answer the question of why I can't get this work from MyEclipse.



Java RMI does require a server to be running. An RMI server. Tomcat is an HTTP server. It doesn't have any RMI support built into it.

To test RMI in eclipse, you have to launch an RMI server from Eclipse OR you have to attach the Eclipse debugger to the RMI server as a remote debugging session (this requires the RMI server to be launched with debugging enabled so that it will open a network port for Eclipse to debug through). Then you launch the client app in Eclipse, You can set breakpoints in both client code and server code, but Eclipse does have to have an up-to-date copy of the server's RMI service source code available so that it will know the proper line numbers.
 
Clayton Cramer
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Okay, this helps. Let me ask you a more detailed questions:

"To test RMI in eclipse, you have to launch an RMI server from Eclipse OR you have to attach the Eclipse debugger to the RMI server as a remote debugging session (this requires the RMI server to be launched with debugging enabled so that it will open a network port for Eclipse to debug through)."

It appears that the magic incantation on the server command line arguments is:

-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=n -Djava.rmi.server.logCalls=true -Dsun.rmi.loader.loglLevel=5 -Dsun.rmi.server.exceptionTrace=true -Dsun.rmi.server.logLevel=5

I am guessing on the logLevel values.

I am still running into the problem with

java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:1099 connect,resolve)

This seems to be a security policy problem, which I still have not figured out. I am passing -Djava.security.policy=server.policy, where server.policy is the name of a file containing

grant codeBase "file:/C:/tomcat5/webapps/rmi/-" {
permission java.security.AllPermission;
};

Yes, I am not relying on Tomcat, but that's where the file is.

Should I specify a fully qualified path to where server.policy is located?
 
Tim Holloway
Saloon Keeper
Posts: 27752
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Last time I had a webapp as an RMI client, I think I had a security policy for Tomcat, but not for the RMI Server. Since the RMI server is a stand-alone app, it can pretty much do anything it wants to anyway.

The one thing I can see that I'm not sure of is your URL. The proper syntax, I believe is: "file://C:/tomcat5/webapps/rmi/-". That extra slash after the protocol ID is critical, I believe.

 
Clayton Cramer
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It is unfortunate that the error messages are not a bit more helpful. I have now tried my server.policy file with one, two, and three slashes after file:, and the results are:

One slash:

C:\Documents and Settings\ccramer\Workspaces\MyEclipse 9\rmi-server\src>java -Xd
ebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,address=8000,suspend=n -Dj
ava.rmi.server.logCalls=true -Dsun.rmi.loader.loglLevel=5 -Dsun.rmi.server.excep
tionTrace=true -Dsun.rmi.server.logLevel=5 -cp .;c:\tomcat5\webapps\rmi\compute.
jar -Djava.security.manager -Djava.rmi.server.codebase=file:/c:\tomcat5\webapps\
rmi\compute.jar -Djava.security.policy=file:/c:/tomcat5/webapps/rmi/server.polic
y engine.ComputeEngine
Listening for transport dt_socket at address: 8000
Oct 17, 2012 10:21:16 AM sun.rmi.server.UnicastRef newCall
FINE: main: get connection
ComputeEngine exception:
java.security.AccessControlException: access denied (java.net.SocketPermission 1
27.0.0.1:1099 connect,resolve)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkConnect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(Unknown S
ource)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown S
ource)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.newCall(Unknown Source)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at engine.ComputeEngine.main(ComputeEngine.java:36)

Two slashes:

identical

Three slashes:

identical

One would almost get the impression that it is not even seeing the server.policy file. Perhaps the problem is the -Djava.security.policy= parameter? I suppose that I can try changing the number of slashes there next. And I did, with one, two, and three slashes after file: on the command line arguments, without any change in behavior.
 
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I found that to start my RMI server, the java.security.policy property needed quotes around its value. And apparently it isn't a URL so you don't need the file: prefix. So not this:



but this:


 
Clayton Cramer
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is very useful information! Thank you! What about in the server.policy file itself? Currently I have:

grant codeBase "file:///C:/tomcat5/webapps/rmi/-" {
permission java.security.AllPermission;
};

My suspicion is that since the server.policy file is referenced directly (not by a URL) that perhaps the codeBase parameter should also be just a file name. But that does not seem to work any better.
 
Clayton Cramer
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:he one thing I can see that I'm not sure of is your URL. The proper syntax, I believe is: "file://C:/tomcat5/webapps/rmi/-". That extra slash after the protocol ID is critical, I believe.


It appears from reading http://docs.oracle.com/javase/1.4.2/docs/guide/rmi/codebase.html that file:/// (three slashes) is required.
 
Paul Clapham
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The file:// protocol was badly described at the beginning, or so I understand, so the required number of slashes is always a questionable item.

The way I look at it, here's how it works.

(1) The protocol part of the URL is "file://" -- with two slashes, just like other protocols you'll be familiar with.

(2) Assuming the file part of the URL is meant to be an absolute path and not a relative path -- the case I've always been dealing with -- then:

(2a) If you're in a Windows environment the file part should start with a drive letter and carry on in the normal way, only with / instead of \ as the separator.

(2b) If you're in a UNIX-like environment the file part should start with a / to denote an absolute path, and carry on in the normal way.

So that's why you'll see people say "use three slashes". The people who wrote the tutorial you linked to were from Sun, a UNIX-oriented company, and quite possibly they didn't want to get into UNIX vs Windows in that level of tutorial. Perhaps they hadn't even tried their examples on a Windows machine.
 
Tim Holloway
Saloon Keeper
Posts: 27752
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Now you know why I was a bit hesitant.

In DOS/Windows, the indication that the path is absolute is a backslash FOLLOWING the drive selector. In most other OS's, the absolute-path marker is the very first character of the path. The double-slashes, as Paul noted, are part of the protocol identification sequence.

So a well-formed absolute path in Windows using the URL notation is "file:///C:/mydir/subdir/file.ext". I have also seen it as "file:///C|/mydir/subdir/file.ext", which is presumably to avoid possible ambiguities using the ":".
 
Clayton Cramer
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I found the answer over at http://patriot.net/~tvalesky/easyrmi.html. Here's an example that worked for me:

-Djava.security.policy=c:\rmi\hello\server.policy

Wow! Surprisingly simple!
 
Paul Clapham
Marshal
Posts: 28177
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:So a well-formed absolute path in Windows using the URL notation is "file:///C:/mydir/subdir/file.ext". I have also seen it as "file:///C|/mydir/subdir/file.ext", which is presumably to avoid possible ambiguities using the ":".



And in a completely unrelated situation yesterday evening (using the document() function in XSLT), I found that "file:///C:/..." gets the file I asked for whereas "file://C:/..." gives me error messages that C is an unknown protocol. So: three slashes good, two slashes bad.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic