RMI上的异常处理

时间:2012-08-21 13:19:01

标签: java exception-handling rmi

我有一个常见的问题,我想听听你对最佳方法的看法。

假设您有一个在分布式服务器系统上运行的应用程序。让我们说前端和后端服务器。后端服务器上的方法通过RMI调用。

后端java进程通常需要与前端java进程不同的库。后端可能会发生运行时异常。抛出的异常不会被后端捕获,因此它会传输到前端服务器。现在的问题是前端不知道异常,因为包不在类路径中(例如EJBTransactionRolledBackException)。抛出另一个异常 - ClassNotFoundException。这使得无法查看execption发生的位置,因为stacktrace不包含来自后端服务器的堆栈。我能想到的另一种情况是异常无法序列化。

你如何解决这个问题?我可以以某种方式记录抛出的任何运行时异常,而不必构建try ... catch和rethrow块吗?

4 个答案:

答案 0 :(得分:5)

  

后端服务器上的方法是通过RMI调用的。

你的问题。 : - )

说真的,最简单的处理方法可能是在服务器上设置以下属性:

-Dsun.rmi.server.exceptionTrace=true

这将为您提供服务器端的异常堆栈跟踪。它不会在客户端修复ClassNotFoundException,但至少在发生这种情况时,您需要深入了解服务器日志以查找更多信息。

此处记录了其他有用的RMI属性:

http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/javarmiproperties.html

http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/sunrmiproperties.html

答案 1 :(得分:1)

  • 您可以尝试使用RMI的codebase功能在需要时获取服务器类。但是,在JBoss上配置是一件痛苦的事。
  • 您可以安装基于Dynamic Proxies的接口层来进行异常转换(在我认为的大多数EJB服务器中都不起作用)
  • 如果您的服务器是JBoss,则可以使用EJB interceptors进行异常转换

我不知道其他服务器在这方面提供了什么。

答案 2 :(得分:0)

我在寻找答案时偶然发现了这个问题。事实证明没有好的答案,但有一些解决方法。

我在http上使用序列化构建了一个简单的rpc协议,它有同样的问题。你可以在这里找到我的半智能解决方案:

https://github.com/stickfigure/trivet/blob/master/src/main/java/com/voodoodyne/trivet/ExceptionalObjectInputStream.java

基本上,在反序列化对象流时,查找以“Exception”结尾的缺失类,并将类描述符与客户端上 的异常类交换。好处是嵌套的堆栈跟踪按原样保留。坏消息是因为这取代了异常类,所以信息丢失了;每个被替换的异常变为ServerSideException。除了消息之外的任何其他数据也被丢弃。通常,从堆栈跟踪和消息中找出正在发生的事情并不是很难,但是这段代码会记录原始异常类型,以防你需要挖掘它。

我怀疑你是否有足够的钩子进入客户端代理以将此技术应用于RMI。

答案 3 :(得分:0)

我对这个问题有点困惑。 由于我们使用前端和后端服务器,为什么不将消息/结果对定义为响应。并且消息不需要是文本,独特的编码系统就足够了,我们可以使用统一的机制将代码转换为前端服务器上的文本消息,类似于Spring Exception转换器所做的那样。