java rmi simple project classNotFoundException binding registry

115 Views Asked by At

Ok, I'm sure this should be pretty easy, but I'm fairly new to Java (I'm more a .NET boy :P) and after following every single recommendation I found here to no success, I think it's time to step back and ask.

I'm trying to start a simple rmi project with a client, a server and a common project where common interfaces are defined. I've just implemented my server code, and when I try to run it to check if everything is fine, I get struck on a java.lang.ClassNotFoundException.

After following several answers on similar issues, I'm fair sure that my problem comes from rmiregistry running on a different location than my project.

I use following code to set registry codebase:

public class Utils {

public static final String CODEBASE = "java.rmi.server.codebase";

public static void setCodeBase(Class<?> c) {
    String ruta = c.getProtectionDomain().getCodeSource().getLocation().toString();

    String path = System.getProperty(CODEBASE);
    if (path != null && !path.isEmpty()) {
        ruta = path + " " + ruta;
    }

    System.setProperty(CODEBASE, ruta);
}

}

Then, I try to start my server code with this main class:

public class MainRegulador {

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

    Utils.setCodeBase(IRegulador.class);
    Registry registro = null;
    Remote proxy = null;

    try {

        Regulador myReg = new Regulador();
        proxy = UnicastRemoteObject.exportObject(myReg, 36510);

        registro = LocateRegistry.getRegistry();
        registro.rebind("Distribuidor", proxy);  //this is the line where exception is thrown

        System.out.println("El Regulador está corriendo. Pulse ENTER para finalizar el proceso.");
        System.in.read();

    } catch(Exception ex) {

        System.out.println("No se ha logrado inicializar el Registrador");
        System.out.println(ex.getMessage());

    } finally {

        if (registro != null && proxy != null) {
            registro.unbind("Distribuidor");
            UnicastRemoteObject.unexportObject(proxy, true);
        }

    }
}

}

But when I run it, always get a java.lang.ClassNotFoundException at IRegulador interface.

Now the fun part:

  • I've printed to console java.rmi.server.codebase value, and it's pointing to bin folder of project where IRegulador interface is defined. (file:/F:/Practicas%20y%20dem%c3%a1s/Sistemas%20Distribuidos/common/bin/)
  • Obviously, that project is also set in the classpath of server project (Regulador)
  • Workspace and rmiregistry are on different disks
  • Despite all, it doesn't seem a global classpath problem, as Utils class is on the same project as IRegulador interface, and it runs before the exception is thrown (as java.rmi.server.codebase is correctly set).

I've tried to set the classpath of rmiregistry before calling it (although it is directly discouraged on some answers), but nothing changed. I've also tried to start rmiregistry.exe from Regulador project bin folder, but also seemed to don't change anything.

Coming from a .NET background, I've always found these classpath issues confusing, and this one is starting to consume much more time than I suspect it deserves. I'm in desperate need of help.

UPDATE: I'm starting to think that the problem is within the url it's passed to the codebase from IRegulador.class. If I paste it into windows explorer, the SO is unable to locate it, so I supose that it's being built with some structure problem that prevents the registry to reach the route:

file:/F:/Practicas%20y%20dem%c3%a1s/Sistemas%20Distribuidos/common/bin/

UPDATE2: I thought path route could be too complex, so I decided to simplify it and strip it from any non-straight character. Now codebase value is

file:/F:/Practicas/SD/common/bin/

However the problem persists, I don't know why rmiregistry is unable to reach that folder.

Then I decided to move the whole project to the same disk where rmiregistry is executed, and see if it changes anything. But nothing changed, same problem.

1

There are 1 best solutions below

0
Bardo On

Ok, finally I got it working...

I've just copied rmiregistry.exe into the common/bin folder and launch it directly from there (previously just had called from there).

This seems to fix the problem with the routes (actually it makes the route available to the registry as it's on the same folder, probably all my codebase writting code is superflous now).