Why Does Simple RMI Server Need Codebase?

♀尐吖头ヾ 提交于 2019-12-02 13:10:23

问题


OS: Windows 7
JDK: 1.8.0_05

I am working through some simple RMI tutorials including Oracle's "Compute" sample (compute). Starting my server should not require a codebase, and answers to questions similar to this one say that "the codebase is optional." Yet my server can't register a remote object unless its interface is in some codebase.

I make sure my Compute interface is available to the web server running on localhost, start the registry server like this:

set CLASSPATH=
rmiregistry -J-Djava.rmi.server.codebase="http://localhost:80/"

And everything works fine:

Exporting stub
Locating registry 
Binding stub
ComputeEngine bound

But if I remove Compute.class from the web server's path I get a ClassNotFoundException:

Exporting stub
Locating registry 
Binding stub
java.rmi.ServerException: RemoteException occurred ...: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: edu.uweo.java2.rmi.compute.server.Compute

I can see from the web server log that an attempt was made to download Compute.class:

GET '/edu/uweo/java2/rmi/compute/server/Compute.class'

I also tried starting the registry server without specifying a codebase:

set CLASSPATH=
rmiregistry

When I do it this way nobody tries to contact my web server (which doesn't surprise me) but I still get the ClassNotFoundException.

My code comes right out of Oracle's tutorial with a couple of extra printed diagnostics thrown in:

try
{
    String          name        = "Compute";
    ComputeEngine   engine      = new ComputeEngine();
    System.out.println( "Exporting stub" );
    Compute         stub        = 
       (Compute)UnicastRemoteObject.exportObject( engine, 0 );
    System.out.println( "Locating registry " );
    Registry        registry    = LocateRegistry.getRegistry();
    System.out.println( "Binding stub" );
    registry.rebind( name, stub );
    System.out.println( "ComputeEngine bound" );
}

Can anyone tell me what I'm missing?

Thanks.


回答1:


You are correct, you don't need to use the codebase feature. However that means that your remote interface, the classes it depends on, and the stub if you're using one must be available to both the client and the Registry on their classpaths. The exception you're getting indicates that the Registry doesn't have these classes on its CLASSPATH.




回答2:


The reason it works this way, is that the RMI Registry is implemented itself using RMI. So when you call bind in one application, the actual implementation of Registry within the rmiregistry process will receive a stub object implementing all of your Remote interfaces just as with all RMI invocations passing references to remote objects.

Therefore the rmiregistry process needs access to all remote interfaces implemented by the object you bind but as you already have discovered, its actual contents is irrelevant as the registry will never invoke any methods on it. All it does is handing the remote stub to callers of lookup and in this case the stub is serialized and transmitted to the remote caller’s JVM where an equivalent stub is created, again, implementing all remote interfaces the stub (and hence the original object) has implemented.

So all that happens with the interfaces within the rmiregistry process (if you started it as stand-alone process) is that the information about the remote interfaces implemented by a remote object is recorded, by letting a stub implement them accordingly, and passed to all other remote applications performing a lookup.

In principle it would be possible to implement the entire registry differently by not using RMI and record the implemented interface without the need for their class files, however, that would be a huge effort as you would have to implement all the things you get for free when simply using RMI.

But note that, if you have only a single server, you can simplify everything by letting your server itself create the registry within its own JVM. Then you don’t need to start another process nor think about its classpath/codebase.



来源:https://stackoverflow.com/questions/27671325/why-does-simple-rmi-server-need-codebase

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!