0

i'm trying to implement a basic distributed application using the Java RMI framework.

Implementing it locally, I can do it, but when I want to manage dynamic class loading remotely, by loading the respective .class files of the classes on an HTTP Server in "Remote" (using virtual machines in the same local network), the Client fails to correctly download the .class for the stub:

Exception in thread "main" java.lang.NoClassDefFoundError: Example1 / RemoteAdd).

I have tried to run the Server in a Windows machine together with the RMI Registry, and in another virtual machine with Ubuntu (connected through a LAN) the Client (also in this machine there is also the HTTP Web Server with files. class). But nothing, I get the exception:

Exception in thread "main" java.lang.NoClassDefFoundError: Example1 / RemoteAdd.

IP Window Machine (Server and RMI Registry) : 192.168.56.1

IP Ubuntu Machine (Client and HTTP Server) : 192.168.1.70

This is the Server class:

package Esempio1;


import java.rmi.Naming;
import java.security.Policy;



public class ServerAdd {


    public ServerAdd() {
        try {

            System.setProperty("java.rmi.server.hostname","192.168.56.1");
            System.setProperty("java.rmi.server.useCodebaseOnly","false");
            System.setProperty("java.security.policy","policy.txt");
            System.setProperty("java.rmi.server.codebase","http://192.168.1.70/Root/");
            System.out.println(System.getProperty("java.rmi.server.codebase"));
            System.out.println(System.getProperty("java.rmi.server.useCodebaseOnly"));
            System.setSecurityManager(new SecurityManager());
            RemoteAdd a = new ImpAdd();
            Naming.rebind("add", a);

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void main (String[] args) {
        new ServerAdd();
    }

}

And this is Client:

package Esempio1;

import java.rmi.Naming;



public class ClientAdd {


    public ClientAdd() {
        try {

            System.setProperty("java.security.policy","policy.txt");
            System.setProperty("java.rmi.server.useCodebaseOnly","false");
            System.out.println(System.getProperty("java.rmi.server.useCodebaseOnly"));
            System.out.println(System.getProperty("java.security.policy"));

            if(System.getSecurityManager()==null) {
                System.setSecurityManager(new SecurityManager());

            }

            RemoteAdd a = (RemoteAdd) Naming.lookup("rmi://192.168.56.1:1099/add");

            Integer x = new Integer(8);
            Integer y = new Integer(2);
            Integer c = a.sommaIng(x, y);

            System.out.print(c.getClass()+" "+c);
        } catch (Exception e) {

            System.out.println(e);
        }
    }

    public static void main (String[] args) {
        new ClientAdd();
    }

}


I send the RMI Registry first like this:

start rmiregistry -J-Djava.rmi.server.useCodebaseOnly=false

Then I run the server on the same machine as the Registry, and it runs smoothly...

Finally I run the Client on the Ubuntu machine, and I get this error back:

Exception in thread "main" java.lang.NoClassDefFoundError: Esempio1/RemoteAdd
        at Esempio1.ClientAdd.<init>(ClientAdd.java:23)
        at Esempio1.ClientAdd.main(ClientAdd.java:37)
Caused by: java.lang.ClassNotFoundException: Esempio1.RemoteAdd
        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)
        ... 2 more

Also this is the policy file used :

grant
{
    permission java.security.AllPermission ;
};

The HTTP Server runs on Ubuntu through the Apache2 service and contains a Root folder with Esempio1 inside and all the .class files (192.168.1.70/Root/Esempio1)

Does anyone know where I'm wrong?

user207421
  • 305,947
  • 44
  • 307
  • 483
awesomex35
  • 11
  • 1
  • Any Java program must have direct access to any classes it actually uses directly, such as `RemoteAdd`. The RMI codebase feature does not address this. – user207421 Mar 23 '19 at 09:32
  • But the codebase, is not it to guarantee the dynamic download of the classes just for this? That is, if the class is not present together with the .class file Client.class, when I run it, will it be downloaded to me from the defined HTTP Server? Otherwise what is the codebase and the dynamic download useful for? – awesomex35 Mar 23 '19 at 10:16
  • It provides downloading of classes *not actually named in the client*, but whose instances are sent by the peer or RMI, such as the stub. – user207421 Mar 24 '19 at 22:11

0 Answers0