Search code examples
javarmidistributed-computing

Running an RMI application from Command Prompt


I have been developing a (somewhat complex) application using RMI to read a file and JSON its contents. I have been coding this app on Netbeans 6.7, therefore I have a folder structure as follows:

Under C:\MyApp:

-build

--- classes

------- MyApp <--- That's a package. My .class files are in there. Also, I ran rmiregistry from here.

-dist

---lib

--------- [some .jar libraries]

-src

...

[Some files]

My application uses a library from the dist\libs folder, and it loads a single file for reading from the current directory, in the [Some files] section.

However, whenever I run the application using: (from the build\classes folder)

java -cp .;..\..\dist\lib\gson-1.4.jar;..\..\..\MyApp -Djava.security.policy=C:\java.policy MyApp.Main

I keep getting ClassNotFoundException errors and a list of errors regarding my RMI interface not being found. The one time it ran, it could not locate the file I need to read. (Got a NullPointerException in my app).

Would you people be able to tell me what I am doing wrong? I believe it's related to the classpath.

Also, if there was a way to run the RMI application from Netbeans itself, it'd be great, but I haven't been able to find any way to do this while searching around.

Oh, rmiregistry is running. And my policy file contains a simple, one-line grant All.

Please help! Thanks!


Solution

  • I think you sould provide c:\MyApp\build\classes in the classpath and NOT the ..\..\..\MyApp thing that I understand is your project base directory.

    At least... with that your java will have access to the classes of your project.

    EDIT: example of application without RMIRegistry

    If you run your application (the server-side) normally you can publish your RMI-object without rmiregisty tool. It simple creates its own registry reserving and listening in some port you choose.

    It's a working example from an application I've made.

    The client application will only have to have the interface of the object in its classpath (and all referenced interfaces and classes of course!).

    BatchServer is the RMI-object implementing the RMI interface (BatchService) and not extending nothing in particular.

    public static void publishAndRun(int port, String name, BatchServer server) throws RemoteException, AlreadyBoundException, NotBoundException
    {
        Registry registry = LocateRegistry.createRegistry(port);
        GPRSService stub = (BatchService) UnicastRemoteObject.exportObject(server, 0);
        try
        {
            registry.bind(name, stub);
            try
            {
                server.run();
            }
            finally
            {
                registry.unbind(name);
            }
        }
        finally
        {
            UnicastRemoteObject.unexportObject(server, true);
        }
    }
    

    Your client application will have to look for YOUR registry in machine:port and ask for the name object:

        Registry registry = LocateRegistry.getRegistry(server, port);
        BatchService gprs = (BatchService)  registry.lookup(name);