当前位置: 首页 > 知识库问答 >
问题:

Java RMI:setup-method 立即返回,并且不创建 RMI 线程

孙京
2023-03-14

我正在尝试设置一个简单的RMI服务器,该服务器绑定到注册表,供客户端获取以进行所有进一步的通信。我正在使用下面的代码:

public class RMIServer implements ServerInterface {

    static Registry reg;

    public static void main(String[] args) throws NoSuchObjectException {
        //Registry reg;
        try {
            reg = LocateRegistry.createRegistry(1099);
            System.out.println("Registry created.");
        } catch (RemoteException ex) {
            System.err.println("Registry already existed.");
            return;
        }
        ServerInterface server = new RMIServer();
        ServerInterface stub;
        try {
            stub = (ServerInterface)UnicastRemoteObject.exportObject(server, 0);
        } catch (RemoteException ex) {
            System.err.println("Could not create stub.");
            ex.printStackTrace();
            return;
        }
        try {
            reg.rebind("server", stub);
            System.out.println("Server bound to registry.");
        } catch (RemoteException ex) {
            System.err.println("Could not bind server to registry.");
            ex.printStackTrace();
            //UnicastRemoteObject.unexportObject(server, true);
            return;
        }
    }
    ...
}

当在我的本地机器上测试时,这工作得非常好,我能够在(本地)客户机和服务器之间建立连接。上面的main方法不会退出,直到我手动终止它,这是预期的行为。我的本地机器(Win8)运行的是Java 1.7.0_17 64位。

现在,当我在带有OpenJDK(版本1.7.0_55 64位)的Ubuntu 12.04服务器上执行与上述相同的代码时,主方法和整个JVM立即退出并且RMI线程不运行。未打印错误消息;我只收到有关正在创建的注册表和服务器绑定到注册表的消息。显然,客户端无法连接,因为服务器上没有RMI进程正在运行。

据我所知,只要有我没有再次取消导出的导出对象,主方法就不应该自动退出。然而它在我的一台机器上确实如此。

有人知道我在这里缺少什么吗?

谢谢大家!

更新1:(对不起,最近很忙,直到现在才有机会进一步了解)。即使在更新到Ubuntu 14.04之后,Java 6、7、OpenJDK和Sun版本的问题仍然存在。

然而,我设法在云中托管的完全不同的机器上重现了这个问题,也运行Ubuntu server 14.04 x64(尽管除了java安装之外,几乎完全干净)。不过,我仍在试图弄清楚如何准确地复制它(当我知道更多时会更新)。

在两台机器上重新启动系统时,问题就消失了(似乎是暂时的)。为了完整性:奇怪的是,当系统日志级别设置为FINE或FINEST时,代码突然像预期的那样运行。我仍然感到困惑。

共有1个答案

闻昊英
2023-03-14

将“reg”变量设为静态。否则它会被GC和DGC取消导出,这反过来会导致服务器的DGC及其取消导出,这反过来又会导致套接字关闭和侦听线程退出。

 类似资料:
  • 问题内容: 我有一个使用pthread的C程序。 我希望新创建的线程在创建后立即运行。 这背后的原因是我的线程具有用于设置信号处理程序的初始化代码,并且在主线程发送一些信号之前,我必须确保处理程序已就绪。 我尝试过紧随其后的尝试,但没有成功。 我怀疑这会有所不同,但是我在x86_64上运行Linux 3.6。 谢谢 问题答案: 或者,您可以使用屏障,即调用pthread_barrier_wait(

  • input Type="hiddit"name="RM"value="0"结束交易后,Paypal返回到input Type="hiddit"name="return"中定义URL(不包括GET中的支付变量), 如果我设置输入类型=“hidden”name=“rm”value=“2”在结束交易后,在输入类型=“hidden”name=“return”中定义的URL处Paypal返回,并在POST中

  • 在过去的几个月里,我一直在阅读C#中的异步等待以及如何正确使用它。 出于实验室练习的目的,我正在构建一个小型Tcp服务器,它应该为连接到它的客户端提供服务。该程序是一个控制台应用程序。 我使用while循环等待连接,如下所示: 所以,到目前为止,我所做的方法ProcessClientAsync被标记为异步无效,我只称之为ProcessClientAsync(客户端),调用将立即返回给调用方。然而,

  • 问题内容: 我 从http 函数进行了如下简单 下载 (为简化起见,省略了错误处理): 但是,由于我异步调用了数十次,因此很少有人报告错误,因为抱怨无法在找到文件。 我使用了相同的URL列表进行测试,但失败了大约30%。一次下载一个相同的URL列表。 测试了一下,我发现下面的代码 并非总是打印,但有时第一个答案打印。 我怀疑太多的异步调用不能保证文件的创建。这是真的?有什么方法可以保证文件创建?

  • 我正在尝试使用数据库的第一个图像设置ImageView。由于某种原因,它不起作用,我不知道为什么。方法loadImage在不同的类中调用。 我还试着用一个单独的方法设置图像,但我需要在创建整个舞台场景等的同时调用它,即使从第二个方法那样调用它,它也不起作用。 这是持有setImage的类 当调用时,设置图像会给我一个null值,imageview的默认值为null,但实际上我正在加载一个图像,甚至