RMI createRegistry delay problem
I'm experiencing a strange and intermittent problem creating an RMI registry from within the JVM. This code will all be run on an intranet, and the idea is to be able to launch services on a bunch of machines easily.
public static <X, Y> void newServer(Function<X, Y> function, String name)
throws Exception {
FunctionServer<X, Y> fun = null;
RemoteFunction<X, Y> stub = null;
Registry registry = null;
try {
fun = new FunctionServer<X, Y>(function);
stub = (RemoteFunction<X, Y>) UnicastRemoteObject.exportObject(fun, 0);
}
catch (RemoteException e1) {
e1.printStackTrace();
}
boolean foundPort = false;
int port = 1099;
do {
try {
registry = LocateRegistry.createRegistry(port);
registry.rebind(name, stub);
// Thread.sleep(100);
foundPort = true;
}
catch (ExportException e) {
port++;
}
catch (Exception e) {
e.printStackTrace();
throw e;
}
} while (!foundPort);
if (registry.lookup(name) != null)
System.out.println("Service " + name + " serving "
+ function.getClass().getCanonicalName() + " on port 开发者_JAVA百科" + port);
}
There is of course a very simple main method:
FileSystemXmlApplicationContext context =
new FileSystemXmlApplicationContext(args[0]);
Object obj = context.getBean(args[1]);
if (obj instanceof Function<?, ?>) {
Function<?, ?> fun = (Function<?, ?>) obj;
FunctionServer.newServer(fun, args[2]);
}
The code is invoked from the command line as follows:
java -cp daopt.jar -Djava.rmi.server.codebase="file://daopt.jar" ****.*******.remote.FunctionServer spring/rosenbrockServer.xml rosenbrock rosenbrock
Sometimes, though, it fails silently. It prints the successful server start message, but then there is no java process running, and netstat -anp | grep [portNumber] shows nothing. Remarkably, if I put in a delay in the newServer method i.e., uncomment the line
Thread.sleep(100);
it all works fine. Does this mean that LocateRegistry.createRegistry is launching some sort of worker thread that throws an exception after a while? What's going on?
Flummoxed,
DevMake the 'registry' variable a static member. At the moment it is being garbage-collected, which unexports it, and allows the server to be DGC'd, which allows the process to exit.
You don't need that do/while loop. Use Registry.REGISTRY_PORT. That's what it's for. Reserved at IANA for the RMI Registry.
When using LocateRegistry.createRegistry within the JVM, it's advisable to use
final Registry registry = LocateRegistry.createRegistry(port);
精彩评论