• 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

Classpath Issue

 
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I am trying to run an RMI example from the book Core Java(TM) 2, Volume II--Advanced Features (7th Edition) and I'm hitting a classpath issue that I cannot figure out. Would anyone know what the solution is here?

The example is a simple example where the class WarehouseClient.java simply makes a call via RMI to run a method on WarehouseServer.java that returns a value. The code for WarehouseClient is listed below. A webserver called NanoHTTPD.java is used to dynamically deliver class files.

The file NanoHTTPD.java is an embeddable HTTP server which I got from here http://elonen.iki.fi/code/nanohttpd/ , so I have not listed the code for that. All the other relevant code to reproduce this is listed at the bottom.

Here is the directory structure that I have:


Here are the commands I run:

* C:\rmiregistry
* E:\RMI-EXAMPLE-1\java -cp . core.java.book.chpt10.example.NanoHTTPD 8080
* E:\RMI-EXAMPLE-1\java -cp . -Djava.rmi.server.codebase=http://localhost:8080/ core.java.book.chpt10.example.WarehouseServer
* E:\RMI-EXAMPLE-1\java -cp .java -cp . core.java.book.chpt10.example.WarehouseClient


The works and the WarehouseClient gets the value back from the WarehouseServer.


Now, here is my problem. If I make a small change to the structure of my directories, as follows, it stops working.




Here are the commands I run:

* C:\rmiregistry
* E:\RMI-EXAMPLE-2\java -cp classes core.java.book.chpt10.example.NanoHTTPD 8080
* E:\RMI-EXAMPLE-2\java -cp classes -Djava.rmi.server.codebase=http://localhost:8080/ core.java.book.chpt10.example.WarehouseServer


But the WarehouseServer throws an exception that it cannot find the Warehouse.class file - I've listed the exception below. Which is strange as I've included the classes directory on the classpath, so why can't it find the class?

Any ideas why this class cannot be found?


Thanks,

Sean.












 
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's all about the directory structure in my opinion. So you have to execute from the correct current directory. If the directory "classes" is a child of directory "RMI-EXAMPLE-2" and you execute the java command from E, then the correct statement to start the server would be:

java -cp RMI-EXAMPLE-2/classes -Djava.rmi.server.codebase=http://localhost:8080/ core.java.book.chpt10.example.WarehouseServer

Anyhow when I try to start the WarehouseServer with correct classpath settings (with regard to the current directory) the program runs without exception.
 
Sean Keane
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ah, darn, I made a mistake in my initial post with regards to the location the Java.exe is run from. I have updated. It should have read:

Here are the commands I run:

* C:\rmiregistry
* E:\RMI-EXAMPLE-2\java -cp classes core.java.book.chpt10.example.NanoHTTPD 8080
* E:\RMI-EXAMPLE-2\java -cp classes -Djava.rmi.server.codebase=http://localhost:8080/ core.java.book.chpt10.example.WarehouseServer


Running the server from "E:\RMI-EXAMPLE-2\" and setting the classpath to "classes" fails to work and I get the exception originally mentioned.
 
Sean Keane
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Roel De Nijs wrote:It's all about the directory structure in my opinion. So you have to execute from the correct current directory. If the directory "classes" is a child of directory "RMI-EXAMPLE-2" and you execute the java command from E, then the correct statement to start the server would be:

java -cp RMI-EXAMPLE-2/classes -Djava.rmi.server.codebase=http://localhost:8080/ core.java.book.chpt10.example.WarehouseServer

Anyhow when I try to start the WarehouseServer with correct classpath settings (with regard to the current directory) the program runs without exception.



Hmmm...this is strange. Even when I try as you suggested Roel I get the exception. So I ran the following command from the directory "E:\"

java -cp RMI-EXAMPLE-2/classes -Djava.rmi.server.codebase=http://localhost:8080/ core.java.book.chpt10.example.WarehouseServer

I'm running on Windows XP using this version of Java:

java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) Client VM (build 16.0-b13, mixed mode)
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I ran your example again and had no problems.

In my current directory (C:\java\workspace) I have a "RMI" folder and inside this directory I have a "bin" folder containing the class files.

C:\java\workspace>java -cp bin -Djava.rmi.server.codebase=http://localhost:8080/ core.java.book.chpt10.example.WarehouseServer
Exception in thread "main" java.lang.NoClassDefFoundError: core/java/book/chpt10/example/WarehouseServer
Caused by: java.lang.ClassNotFoundException: core.java.book.chpt10.example.WarehouseServer
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
Could not find the main class: core.java.book.chpt10.example.WarehouseServer. Program will exit.

C:\java\workspace>java -cp RMI/bin -Djava.rmi.server.codebase=http://localhost:8080/ core.java.book.chpt10.example.WarehouseServer
Constructing server implementation...
Binding server implementaiton to registry...
 
Sean Keane
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hmmm. Thanks for testing that Roel. I replicated your setup and I still get the same exception thrown (see below).

What command are you using to running to start the RMI registry and webserver?

I am using:

* C:\java\workspace>java -cp RMI/bin core.java.book.chpt10.example.NanoHTTPD 8080
* C:\rmiregistry

I wonder is there some networking issue at play on my side?



C:\java\workspace>java -cp RMI/bin -Djava.rmi.server.codebase=http://localhost:8080/ core.java.book.chpt10.example.WarehouseServer

Constructing server implementation...
Binding server implementaiton to registry...
Exception in thread "main" javax.naming.CommunicationException [Root exception is java.rmi.ServerException: RemoteException occurr
ed in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: core.java.book.chpt10.example.Warehouse]
at com.sun.jndi.rmi.registry.RegistryContext.bind(RegistryContext.java:126)
at com.sun.jndi.toolkit.url.GenericURLContext.bind(GenericURLContext.java:208)
at javax.naming.InitialContext.bind(InitialContext.java:400)
at core.java.book.chpt10.example.WarehouseServer.main(WarehouseServer.java:17)
Caused by: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: core.java.book.chpt10.example.Warehouse
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:396)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:250)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:359)
at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
at com.sun.jndi.rmi.registry.RegistryContext.bind(RegistryContext.java:120)
... 3 more
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: core.java.book.chpt10.example.Warehouse
at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:386)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:250)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassNotFoundException: core.java.book.chpt10.example.Warehouse
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:711)
at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:655)
at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:592)
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:1530)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1492)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
... 12 more
 
Sean Keane
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I disconnected myself from my network\internet, rebooted, and ran all the commands again. Same problem, the same exception is getting thrown.

This is very strange, I'm not sure what to try now.

The webserver is providing the class file. I can see this from the command prompt for the webserver after I start WarehouseServer.

Any ideas of what to try?


C:\java\workspace>java -cp RMI/bin core.java.book.chpt10.example.NanoHTTPD 8080
NanoHTTPD 1.21 (C) 2001,2005-2011 Jarno Elonen and (C) 2010 Konstantinos Togias
(Command line options: [port] [--licence])

Now serving files in port 8080 from "C:\java\workspace"
Hit Enter to stop.

GET '/core/java/book/chpt10/example/Warehouse.class'
HDR: 'connection' = 'keep-alive'
HDR: 'accept' = 'text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2'
HDR: 'host' = 'localhost:8080'
HDR: 'user-agent' = 'Java/1.6.0_22'
 
Sean Keane
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is crazy! Just to confirm I am not going mad. I tried the commands from my first example using your setup Roel, as follows

C:\>rmiregistry
C:\java\workspace\RMI\bin>java -cp . core.java.book.chpt10.example.NanoHTTPD 8080
C:\java\workspace\RMI\bin>java -cp . -Djava.rmi.server.codebase=http://localhost:8080/ core.java.book.chpt10.example.WarehouseServer


The WarehouseServer starts fine and throws no exception.

The two main things I see mentioned when RMI is not working is

1) Security issues
2) Classpath issues

I'm ruling out security, as the example above works, so it couldn't be security issues?

That leaves me with a classpath issue, but I can't see what the issue is? Any ideas folks?

Roel, I'm presuming when you are running the commands, that the CLASSPATH variable does not contain a path to your class files for this example?
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sean,

To be honest I ran the code without using this NanoHTTPD server. Shame on me As a side note you are making things more complex than needed: using a http server to serve your class files. I guess it just makes part of your learning part

I tried it now completely with the NanoHTTPD and I got it to work. I think you have to make sure that this http server is serving the files from the correct directory. So again with my setup:

1. start rmiregistry
2. start the http server
C:\java\workspace\RMI\bin>java -cp . core.java.book.chpt10.example.NanoHTTPD 8081 (it's really important that you serve files from the correct directory: not "workspace", not "workspace/RMI", but "workspace/RMI/bin" is the correct directory for serving your class files)
Now serving files in port 8081 from "C:\java\workspace\RMI\bin"
Hit Enter to stop.

3. run the WarehouseServer
C:\java\workspace\RMI\bin>java -cp . -Djava.rmi.server.codebase=http://localhost:8081/ core.java.book.chpt10.example.WarehouseServer
Constructing server implementation...
Binding server implementaiton to registry...
Waiting for invocations from clients...

4. run the WarehouseClient
C:\java\workspace\aclvb\RMI\bin>java -cp . core.java.book.chpt10.example.WarehouseClient
RMI registry bindings: central_warehouse
Blackwell Toaster:24.95


Hope it helps!
Good luck!
Kind regards,
Roel
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Sean Keane wrote:This is crazy! Just to confirm I am not going mad.


No, you are not going mad You just made sure the http server is serving files from the correct directory, namely C:\java\workspace\RMI\bin. If you start the server from any other directory, the WarehouseServer class will not be found. So it's a hidden classpath issue, because you want to use a http server to serve the files you need to start the WarehouseServer
 
Sean Keane
Ranch Hand
Posts: 590
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ah, legend! Thanks Roel. I guess it required a bit more playing around on my behalf.

The problem seems to be as you reported - you need to start the webserver in the root directory of Java package containing the classes to be served, otherwise the webserver cannot find them when requested for them.

In more concrete terms:
- I was starting my webserver in the directory E:\RMI-Example-2
- The path to the class being requested was E:\RMI-Example-2\classes\core\java\book\chpt10\example\Warehouse.class
- The webserver got a request for '/core/java/book/chpt10/example/Warehouse.class'
- The webserver was looking at the following location 'E:/RMI-Example-2/core/java/book/chpt10/example/Warehouse.class' as the webserver is set up to start looking from the root of the directory from it was launched from i.e. E:\RMI-Example-2

- Now, start the webserver in the directory E:\RMI-Example-2\classes
- The webserver once again gets a request for '/core/java/book/chpt10/example/Warehouse.class'
- But this time it is looking at the following location 'E:/RMI-Example-2/classes/core/java/book/chpt10/example/Warehouse.class' , and it successfully finds the file

Just for my own curiosity, I actually ran the WarehouseServer from the directory E:\RMI-Example-2 to rule out the problem being a classpath issue with the WarehouseServer class, and to see if it was just a problem with the webserver.

I ran the following and all commands ran successfully without any exception being thrown:

* C:\>rmiregistry
* E:\RMI-Example-2\classes>java -cp . core.java.book.chpt10.example.NanoHTTPD 8080
* E:\RMI-Example-2>java -cp classes -Djava.rmi.server.codebase=http://localhost:8080/ core.java.book.chpt10.example.WarehouseServer
* E:\RMI-Example-2>java -cp classes core.java.book.chpt10.example.WarehouseClient


So, I conclude the problem is just with the webserver - it needs to be started from the root directory containing the Java package.

Problem solved! Thanks again Roel, appreciate the help.
 
The City calls upon her steadfast protectors. Now for a tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic