我正在运行两个包含无状态会话EJB的glassfish v2域。在少数情况下,一个域中的EJB必须在另一个域中调用一个EJB。
我的问题是,当被调用的EJB以异常中止时,调用者不会收到异常消息,而是报告一个内部错误,在诊断问题时根本没有用。会发生什么似乎是这样的:
org.omg.CORBA.portable.ApplicationException
,它已经丢失了除该类之外的所有关于异常的详细信息。在com.sun.jts.CosTransactions.TopCoordinator.get_txcontext()
内,回滚的事务ass的状态导致抛出org.omg.CosTransactions.Unavailable
,它被包装并传递几次并最终导致此错误显示为用户:
org.omg.CORBA.INVALID_TRANSACTION: vmcid: 0x0 minor code: 0 completed: No
at com.sun.jts.CosTransactions.CurrentTransaction.sendingRequest(CurrentTransaction.java:807)
at com.sun.jts.CosTransactions.SenderReceiver.sending_request(SenderReceiver.java:139)
at com.sun.jts.pi.InterceptorImpl.send_request(InterceptorImpl.java:344)
at com.sun.corba.ee.impl.interceptors.InterceptorInvoker.invokeClientInterceptorStartingPoint(InterceptorInvoker.java:271)
at com.sun.corba.ee.impl.interceptors.PIHandlerImpl.invokeClientPIStartingPoint(PIHandlerImpl.java:348)
at com.sun.corba.ee.impl.protocol.CorbaClientRequestDispatcherImpl.beginRequest(CorbaClientRequestDispatcherImpl.java:284)
at com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.request(CorbaClientDelegateImpl.java:184)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:186)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:152)
at com.sun.corba.ee.impl.presentation.rmi.bcel.BCELStubBase.invoke(BCELStubBase.java:225)
我能在这里做些什么来保存有关问题实际原因的信息吗?
答案 0 :(得分:1)
问题的原因应该在托管有问题的EJB的域的服务器日志中提供。
听起来从另一端获取更多信息可能很困难......我不知道在创建/抛出ApplicationException时丢失信息的哪个问题跟踪器是正确的。
完全破解是在项目中创建一组自定义异常类,其中ejb已失败。您可以使它们非常精细,以涵盖问题的可能原因,并在其名称中提供足够的详细信息以识别问题的实际位置。哎呀......但是在提交问题并分发修复程序之前,这可能是唯一的选择。
答案 1 :(得分:1)
我能在这做什么吗? 保留有关实际的信息 问题的原因?
不幸的是,没有。 ORB不对系统异常使用普通对象序列化(即org.omg.CORBA。*),这意味着原因丢失。正如@vkraemer所说,你需要依赖服务器日志。
答案 2 :(得分:0)
我终于明白了这一点:实际上,Glassfish通过IIOP非常正确地传输异常并且一切正常......除非你像这样做一些愚蠢的事情:
try{
ejb.getFoo();
}catch (Exception e){
// try again
ejb.getFoo();
}
是的,这是我们自己的该死的代码吞噬了异常并试图在由于异常而被回滚的分布式事务中调用需要事务的EJB方法。