Out*_*mer 2 java exception-handling rmi
抛出RemoteExceptions时使用异常链接是一个坏主意吗?我们有一个RMI服务器,它执行以下操作:
public Object doSomething() throws RemoteException
{
try
{
return getData();
}
catch (CustomException ex)
{
throw new RemoteException(ex);
}
}
Run Code Online (Sandbox Code Playgroud)
我在客户端中遇到由ClassNotFoundException引起的UnmarshallException.从好的方面来看,事实证明CustomException本身是导出的.不幸的是,这个人内部的另一个异常是没有导出,这是ClassNotFoundException的来源.我认为层次结构是这样的:
RemoteException - > CustomException - > SQLException - > NotExportedException
我看到的问题是,即使我们可以保证导出CustomException,我们也无法保证任何较低级别的异常.
因为这个原因,我倾向于永远不要使用RemoteExceptions进行异常链接.相反,我认为我应该在服务器端记录堆栈跟踪并抛出一个简单的vanilla RemoteException,并没有链接到它的"cause"异常.以前有人处理过这种情况吗?
您可以修改远程接口,而不是将RemoteException包装在RemoteException中:
interface Foo extends Remote {
Object doSomething() throws CustomException, RemoteException;
}
Run Code Online (Sandbox Code Playgroud)
这里的原则是只有RMI运行时应该引发RemoteExceptions; 它们表示远程处理有些失败,而不是应用逻辑.实际上,具体实现甚至不需要声明RemoteException
.
但是,这不处理您的服务从某些第三方库捕获异常但不希望在throws子句中公开它的情况.
public Object doSomething() throws CustomException {
try {
return theirSvc.getData();
} catch (ThirdPartyException ex) {
throw new CustomException("Failed to obtain requested data.");
// or: throw new CustomException("Failed to obtain requested data.", ex) ?
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我建议您不要创建"漏洞抽象",其中将在客户端中创建依赖关系,否则无需了解该第三方库.
通常,记录和抛出是不好的做法,因为重复记录相同的错误.但在这种情况下,我认为这是合理的,因为抛出的异常被传递给客户端; 在客户端和服务器上记录它可能很有用.所以catch块最终看起来像这样:
catch (ThirdPartyException ex) {
String message = "Failed to obtain requested data.";
log.error(message, ex);
throw new CustomException(message);
}
Run Code Online (Sandbox Code Playgroud)
这样,ThirdPartyException依赖关系仅限于服务器,服务器日志包含适当的特定于实现的信息,并且错误被正确地报告给客户端.
归档时间: |
|
查看次数: |
1935 次 |
最近记录: |