RMI exception handling

I have a common problem when I would like to hear your opinion that this is the best way to do this.

Suppose you have an application running on a distributed server system. Let the interface and the server speak. Methods on the server server called through RMI.

The backend java process usually needs different libraries than the java process interface. It is possible that a run-time exception is thrown in the backend. The thrown exception does not get into the backend, and therefore it is moved to an external server. The problem is that the interface does not know an exception, because the package is not in the classpath (for example, EJBTransactionRolledBackException). Another exception is thrown - a ClassNotFoundException. This makes it impossible to see where the execution occurred, because stacktrace does not include the stack from the server server. Another scenario that I can think of is where the exception cannot be serialized.

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

+4
source share
4 answers

Methods on the backend server are invoked through RMI.

Well, there is your problem. :-)

Seriously, the easiest way to handle this is to probably set the following property on the server:

-Dsun.rmi.server.exceptionTrace=true 

This will give you a server side exception stack trace. It will not fix a Client-side ClassNotFoundException , but at least when that happens, you know to dig through the server logs to find out more information.

Other useful properties of RMI are described here:

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

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

+5
source
  • You can try the codebase RMI function to get server classes when needed. However, it is a pain to tune in to JBoss
  • You can set the interface layer based on Dynamic Proxies to throw exceptions (will not work on most EJB servers, I think)
  • If your server is JBoss, you can use EJB hooks to throw exceptions

I do not offer other servers in this direction.

+1
source

I came across this question, looking for the answer itself. It turns out there is no good answer, but there are workarounds.

I built a simple rpc protocol using serialization over http, which has the same problem. You can find my semi-smart solution to the problem:

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

Basically, when deserializing an object stream, find the missing classes ending in "Exception" and replace the class descriptor with the exception class that is on the client. The surface is that nested stack traces are saved as they are. The bad news is that since this replaces the exception class, this information is lost; each exception thrown becomes a ServerSideException . In addition, any additional data other than the message is discarded. It is usually not too difficult to understand what comes from the stacktrace and the message, but this code registers the original type of exception if you need to dig it out.

I doubt that you get enough hooks to the client proxy to apply this technique to RMI.

0
source

I am a little confused by this problem. Since we use front-end and server-side servers, why not define a couple of messages / results as an answer. And the message does not have to be textual, the unique coding system is good enough, we can translate the codes into text messages on the interface server with a unified mechanism, similar to what the Spring Exception translator does.

0
source

All Articles