【问题标题】:Java UnmarshalException on shutdown / System.exit from MBean via JConsoleJava UnmarshalException on shutdown / System.exit from MBean via JConsole
【发布时间】:2012-09-07 22:42:14
【问题描述】:

我想知道当我使用带有 JConsole 的 MBean 远程执行调用 System.exit(1) 的关闭时如何避免出现此异常。我已经验证当不调用关机时我没有例外,所以其他一切都设置正确。错误是:

Problem invoking shutdown: java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: java.io.EOFException

这当然是有道理的!我只是不希望这是一个错误条件。

【问题讨论】:

  • 你整理了那个错误吗?

标签: java jmx shutdown unmarshalling jconsole


【解决方案1】:

这是意料之中的。我假设您的 JMX 操作是启动 System.exit(1) 的原因?这意味着 Jconsole 正在等待来自服务器的响应,并且在套接字关闭之前没有发送任何响应。即使通过 JMX 调用 void 方法也会等待确认,因此 jconsole 可以说“方法已成功调用”。由于服务器正在关闭,因此您没有收到响应是有道理的。

如果你想避免这种情况,你可以分叉一个线程来休眠一下,然后发出退出。比如:

 public String jmxShutdown() {
     new Thread(new Runnable() {
         public void run() {
             try {
                Thread.sleep(100);
             } catch (InterruptedException e) {
                // ignored
             }
             System.exit(1);
         }
     });
     return "Shutting down";
 }

【讨论】:

  • 没错@djechlin。即使是 void 方法也会等待确认,因此 jconsole 可以说“方法已成功调用”。
【解决方案2】:

根据您的用例,还值得configure your own JMXConnectorServer 并通过 JMX 方法停止连接器服务器,而不是调用 System.exit()。手动配置的连接器服务器正在用户线程中运行,因此当服务器停止时(并且没有其他用户线程在运行),JVM 也会终止。

这种方法的优点是连接器服务器确保在释放其用户线程之前,所有正在运行的 JMX 调用仍然正常处理。我通过创建一个测试 MBean 方法来验证此行为,该方法在连接器服务器上调用 stop() 并在之后休眠一秒钟,并且从 JMX 客户端调用测试方法时我总是得到响应。

【讨论】:

  • 我认为 OP 想要 使用 System.exit(...) 关闭应用程序。
  • 尽管如此,不同的解决方案可能对其他有稍微更一般的问题“如何通过 JMX 关闭进程并仍然接收 JMX 响应”的人有用。我不仅仅是在为 OP 回答这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-31
  • 1970-01-01
相关资源
最近更新 更多