RMI createRegistry延迟问题

发布于 2024-10-07 00:24:30 字数 1868 浏览 3 评论 0原文

我在从 JVM 中创建 RMI 注册表时遇到了一个奇怪且间歇性的问题。这些代码将全部在内部网上运行,其想法是能够轻松地在一堆机器上启动服务。

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 " + port);   
}

当然有一个非常简单的 main 方法:

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]);
}

从命令行调用代码如下:

java -cp daopt.jar -Djava.rmi.server.codebase="file://daopt.jar" ****.*******.remote.FunctionServer spring/rosenbrockServer.xml rosenbrock rosenbrock

但有时,它会默默地失败。它打印成功服务器启动消息,但随后没有 java 进程运行,并且 netstat -anp | grep [portNumber] 没有显示任何内容。值得注意的是,如果我在 newServer 方法中添加延迟,即取消注释该行,

Thread.sleep(100); 

则一切正常。这是否意味着 LocateRegistry.createRegistry 正在启动某种工作线程,该线程在一段时间后抛出异常?这是怎么回事?

困惑,
开发者

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 " + 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,
Dev

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

千纸鹤带着心事 2024-10-14 00:24:30

使“registry”变量成为静态成员。目前它正在被垃圾收集,从而取消导出它,并允许服务器进行 DGC,从而允许进程退出。

您不需要那个 do/while 循环。使用Registry.REGISTRY_PORT。这就是它的用途。由 IANA 为 RMI 注册管理机构保留。

Make 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.

感悟人生的甜 2024-10-14 00:24:30

在 JVM 中使用 LocateRegistry.createRegistry 时,建议使用

final Registry registry = LocateRegistry.createRegistry(port);

When using LocateRegistry.createRegistry within the JVM, it's advisable to use

final Registry registry = LocateRegistry.createRegistry(port);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文