Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaRMI:setup方法立即返回,RMI线程为';t创造_Java_Rmi - Fatal编程技术网

JavaRMI:setup方法立即返回,RMI线程为';t创造

JavaRMI:setup方法立即返回,RMI线程为';t创造,java,rmi,Java,Rmi,我正在尝试设置一个简单的RMI服务器,它绑定到注册表,以便客户端获取所有进一步的通信。我使用的代码如下: public class RMIServer implements ServerInterface { static Registry reg; public static void main(String[] args) throws NoSuchObjectException { //Registry reg; try {

我正在尝试设置一个简单的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位)在Ubuntu12.04服务器上执行上述代码时,主方法和整个JVM立即退出,RMI线程不运行。不打印错误消息;我只收到有关正在创建注册表和服务器绑定到注册表的消息。显然,客户端无法连接,因为服务器上没有运行RMI进程

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

有人知道我在这里遗漏了什么吗

谢谢大家!

更新1: (抱歉,最近很忙,直到现在才有机会进一步了解此内容)。这个问题在Java6、7、OpenJDK和Sun的版本中仍然存在,即使在更新到Ubuntu 14.04之后也是如此

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

在两台机器上重新启动系统时,问题消失了(似乎是暂时的)。
出于完整性考虑:奇怪的是,当系统日志级别设置为FINE或FINEST时,代码突然表现出预期的行为。我还是被难住了

将'reg'变量设为静态。否则,它很容易被GC和DGC撤销,这将导致服务器的DGC及其撤销,进而导致套接字关闭和侦听线程退出。

除了我遇到多个(严重的)问题之外,我无法提供任何真正的见解粘贴中OpenJDK Java实现的问题。如果您可以切换到Sun/Oracle JRE(即使只是为了测试),您的问题很可能会自动解决。谢谢-我已经切换到Oracle Java,确保从机器上删除OpenJDK-结果相同。我在哪台机器上编译源代码也没有区别;它在一台机器上工作,但在另一台机器上不工作。我刚刚用java-6-openjdk-i386在Ubuntu12.04上尝试了你的代码,它的行为与你预期的一样,即进程不会退出,并开始在两个端口(注册表和绑定对象)上侦听。RMI的完整日志记录可能会有所帮助,正如另一条评论中所建议的:有关详细信息,请参阅。无论是什么原因,您都可以通过在设置代码后的无限循环中放置一个sleep()来一次性解决此问题。有趣的是,您能否详细说明为什么reg变量会超出范围并符合GC条件?@ChristopheD您自己刚刚说过。现在它是一个局部变量,所以当main()退出时它就超出了作用域,所以它符合GC的条件。我明白了,但我想这取决于上面代码段中的
隐藏了什么。。。如果某些代码(似乎)
偶然地在某个特定Java实现上工作,而在另一个(例如OpenJDK)上不工作(严格地说是由不同的GC实现引起的),我仍然会觉得“奇怪”。。。作用域规则应该是相同的(如果不是,则会有更多问题:)@EJP感谢您的建议,我已经尝试将reg设置为静态类变量,而不是本地类变量(请参见编辑)-不幸的是,行为没有改变。在Ubuntu机器上,该方法仍然立即存在(现在使用Oracle Java运行)。@ChristopheD没有人说范围规则不同。当然不是。此代码在所有Java版本上都是错误的,除非“…”中存在休眠。