Skip to Main Content

Java APIs

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Classpath Issue

metricspacesMar 3 2011 — edited Mar 10 2011
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 this example 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:
E:\RMI-EXAMPLE-1
+---core
    +---java
        +---book
            +---chpt10
                +---example
                        NanoHTTPD$1.class
                        NanoHTTPD$HTTPSession.class
                        NanoHTTPD$Response.class
                        NanoHTTPD.class
                        NanoHTTPD.java
                        Warehouse.class
                        Warehouse.java
                        WarehouseClient.class
                        WarehouseClient.java
                        WarehouseImpl.class
                        WarehouseImpl.java
                        WarehouseServer.class
                        WarehouseServer.java
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

This 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. All I have done is put my core Java package into a directory called classes. So instead of E:\RMI-EXAMPLE-2 being the root of the package, the directory E:\RMI-EXAMPLE-2\classes is the root directory.

E:\RMI-EXAMPLE-2
+---classes
    +---core
        +---java
            +---book
                +---chpt10
                    +---example
                            NanoHTTPD$1.class
                            NanoHTTPD$HTTPSession.class
                            NanoHTTPD$Response.class
                            NanoHTTPD.class
                            NanoHTTPD.java
                            Warehouse.class
                            Warehouse.java
                            WarehouseClient.class
                            WarehouseClient.java
                            WarehouseImpl.class
                            WarehouseImpl.java
                            WarehouseServer.class
                            WarehouseServer.java
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.

Constructing server implementation...
Binding server implementaiton to registry...
Exception in thread "main" 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: 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
package core.java.book.chpt10.example;

import java.rmi.RemoteException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class WarehouseServer {
	
	public static void main(String[] args) throws RemoteException, NamingException {
		System.out.println("Constructing server implementation...");
		WarehouseImpl centralWarehouse = new WarehouseImpl();
		
		System.out.println("Binding server implementaiton to registry...");
		Context namingContext = new InitialContext();
		namingContext.bind("rmi:central_warehouse", centralWarehouse);
		
		System.out.println("Waiting for invocations from clients...");
	}
}
package core.java.book.chpt10.example;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;


public class WarehouseImpl extends UnicastRemoteObject implements Warehouse {

	private HashMap<String, Double> prices;

	protected WarehouseImpl() throws RemoteException {
		prices = new HashMap<String, Double>();
		prices.put("Blackwell Toaster", 24.95);
		prices.put("ZapXpress Microwave Oven", 49.95);
	}

	@Override
	public double getPrice(String description) throws RemoteException {
		Double price = prices.get(description);
		return price == null ? 0 : price;
	}
}  
package core.java.book.chpt10.example;
import java.rmi.Remote;
import java.rmi.RemoteException;


public interface Warehouse extends Remote {

	double getPrice(String description) throws RemoteException;
}
package core.java.book.chpt10.example;

import java.rmi.RemoteException;
import java.util.Enumeration;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameClassPair;
import javax.naming.NamingException;

public class WarehouseClient {

	public static void main(String[] args) throws NamingException, RemoteException {

		Context namingContext = new InitialContext();
		
		System.out.print("RMI registry bindings: ");
		Enumeration<NameClassPair> e = namingContext.list("rmi://localhost/");
		while(e.hasMoreElements()){
			System.out.println(e.nextElement().getName());
		}
		
		String url = "rmi://localhost/central_warehouse";
		Warehouse centralWarehouse = (Warehouse) namingContext.lookup(url);
		
		String descr = "Blackwell Toaster";
		double price = centralWarehouse.getPrice(descr);
		System.out.println(descr + ":" + price);
	}
}
Edited by: 841344 on Mar 2, 2011 11:47 PM

Edited by: 841344 on Mar 2, 2011 11:48 PM

Edited by: 841344 on Mar 2, 2011 11:50 PM
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Apr 7 2011
Added on Mar 3 2011
5 comments
1,543 views