4

I have a common problem where I would like to hear your opinion on what's the best way to do it.

Assume you have an application that runs on a distributed server system. Let's say frontend and backend server. Methods on the backend server a called through RMI.

The backend java process usually needs different libraries than the frontend java process. It's possible that a runtime exception occurs in the backend. The thrown exception is not caught by the backend and so it travels to the frontend server. The problem now is that the frontend doesn't know the exception because the package isn't in the classpath (e.g. EJBTransactionRolledBackException). Another exception is thrown - ClassNotFoundException. This makes it impossible to see where the execption occured because the stacktrace doesn't include the stack from the backend server. Another scenario I can think of is where the exception cannot be serialized.

How do you solve this problem? Can I somehow log any runtime exception that is thrown without having to build a try ... catch and rethrow block?

4

4 回答 4

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

于 2012-08-22T21:41:53.733 回答
1
  • 您可以在需要时尝试 RMI 的代码库功能来获取服务器类。但是,在 JBoss 上配置很痛苦
  • 您可以安装基于动态代理的接口层来进行异常转换(我认为在大多数 EJB 服务器中都不起作用)
  • 如果你的服务器是 JBoss,你可以使用EJB 拦截器来做异常转换

我没有其他服务器在这个方向上提供什么。

于 2012-08-21T15:21:08.900 回答
0

我对这个问题有点困惑。既然我们使用前端和后端服务器,为什么不将消息/结果对定义为 response 。并且消息不需要是文本,唯一的编码系统就足够了,我们可以在前端服务器以统一的机制将代码翻译成文本消息,类似于 Spring Exception 翻译器所做的。

于 2014-08-23T11:02:16.060 回答
0

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

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

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

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

不过,我怀疑您是否在客户端代理中获得了足够的钩子来将此技术应用于 RMI。

于 2013-07-21T00:44:45.193 回答