- This topic has 6 replies, 3 voices, and was last updated 12 years, 1 month ago by support-piotr.
-
AuthorPosts
-
Clayton E. CramerMemberI 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 have the various components of the demo broken into three separate projects: rmi-base, rmi-client, and rmi-server. They all compile just fine.
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:
java -cp “c:\Documents and Settings\ccramer\Workspaces\MyEclipse 9\rmi\src”;c:\tomcat5\webapps\rmi\compute.jar -Djava.rmi.server.codebase=file:/c:\tomcat5\webapps\rmi\compute.jar -Djava.security.policy=server.policy engine.ComputeEngine
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.policyComputeEngine 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:
META-INF/ META-INF/MANIFEST.MF compute/Compute.class compute/Task.class
Any suggestions?
support-pradeepMemberclaytoncramer,
You need to set java.rmi.server.codebase property. The Server is looking for the Compute class and can’t find it. So therefore the server’s java.rmi.server.codebase property should point to the location where it can find this class.
For further reference please take a look at this thread :
http://code.nomad-labs.com/2010/03/26/an-improved-rmi-tutorial-with-eclipse/Let us know how this works for you.
Clayton E. CramerMemberIt turns out that I did not realize that I needed the RMI client and RMI server executing with different run configurations because of the different environment variables, classpath, arguments, etc. Once I created a separate configuration for both client and server, everything works just fine.
support-pradeepMemberclaytoncramer,
Glad that you got it working.
Let us know if you have any issues.
Clayton E. CramerMemberMy guess is that there is something about how to set up the environment variables for security policy. I built the server and client side using MyEclipse. If I start the server side from the command shell with:
java -cp .;c:\tomcat5\webapps\rmi\compute.jar -Djava.rmi.server.codebase=file:/c:\tomcat5\webapps\rmi\compute.jar -Djava.security.policy="C:\tomcat5\webapps\rmi\server.policy" engine.ComputeEngine
and I start the client side from the command shell with:
java -cp c:\tomcat5\webapps\rmi;c:\tomcat5\webapps\rmi\compute.jar -Djava.rmi.server.codebase=file:/c:\tomcat5\webapps\rmi\ -Djava.security.policy="c:\tomcat5\webapps\rmi\client\client.policy" client.ComputePi localhost 10
everything works: the client code successfully sends a request to the server side, and the client side successfully uses the data to put up a Swing display.
However: if I to start the client side from MyEclipse with what I think is the equivalent run configuration, I get:
ComputePi exception: java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:1099 connect,resolve) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323) at java.security.AccessController.checkPermission(AccessController.java:546) at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at java.lang.SecurityManager.checkConnect(SecurityManager.java:1034) at java.net.Socket.connect(Socket.java:513) at java.net.Socket.connect(Socket.java:469) at java.net.Socket.<init>(Socket.java:366) at java.net.Socket.<init>(Socket.java:180) at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22) at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128) at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:595) at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198) at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184) at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:322) at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source) at client.ComputePi.main(ComputePi.java:19)
The settings in the client run configuration are:
Project: rmi
Main class: client.ComputePi
Program arguments: localhost 10
Runtime JRE: Execution environment: CDC-1.0/Foundation-1.0 (Sun JDK 1.6.0_13)
Classpath: c:\tomcat5\webapps\rmi\
c:\tomcat5\webapps\rmi\compute.jar
Environment (and this is where I suspect the problem lies):
java.rmi.server.codebase file:///c:/tomcat5/webapps/rmi/
java.security.policy file:///client/client.policyI have tried a variety of values for these two environment variables: with and without file:, with and without file:///; with \ or \ instead of / as separators, with quotation marks around the values, all with the same result. I suspect that there is something different about how to set these environment variables from the Run Configuration than from the DOS shell. Any suggestions of what to try next?
What a horrible decisions Microsoft made, long, long ago, when they decided to use backslash as the directory separator, instead of forward slash.
support-pradeepMemberclaytoncramer,
Sorry that you are seeing issues.
I have escalated it to a dev team member. They will get back to you.
support-piotrParticipantClayton,
It seems that variables you want to pass, are not environment variables, but rather JVM variables. You need to enter them on “Arguments” tab in “VM arguments” section in the exact form as on command line (with -D prefix). I hope that will solve your issue!
-
AuthorPosts