我正在使用 Arquillian 运行功能测试,它使用 Java EE 应用程序的完整 WAR,包括实体、EJB 接口(interface)和实现以及安装到本地 Maven 存储库中的 webapp(JSF 页面和支持 bean),即测试非常接近到集成测试。有时,我会遇到类似的堆栈跟踪
SomeRuntimeException
[more container related calls]
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2060)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:220)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:90)
at com.sun.proxy.$Proxy331.ejbMethod(Unknown Source)
at package.JSFManagedBeanClass.method(JSFManagedBeanClass.java:[line number])
当 JSF backingb bean JSFManagedBeanClass
调用注入(inject)了 @EJB
的 EJB 的 ejbMethod
时,例如someEJB.ejbMethod
.
我似乎不知道如何获取由 com.sun.proxy.$Proxy[number].ejbMethod(Unknown Source) 表示的 EJB 中发生异常的行号
在堆栈跟踪中。
我尝试添加
<debug>true</debug>
<debugLevel>lines,vars,source</debugLevel>
到 maven-compiler-plugin
配置,并确定 maven-war-plugin
中是否有一个选项 - 唯一相关的是warSourceInincludes
,但它取决于 warSourceDirectory
,如果仍应包含 webapp 内容,则无法更改该目录。
添加
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<excludes>
<exclude>target/generated-sources</exclude>
</excludes>
</configuration>
</plugin>
到 WAR POM 会导致对 target/generated-sources
执行 maven-checkstyle-plugin
并在生成的 JPA 元模型上失败,这完全没有意义。
Arquillian @Deployment
方法:
@Deployment(testable = false)
public static Archive<?> createDeployment0() {
WebArchive retValue = Maven.configureResolver().workOffline().resolve("[groupId]:[artifactId]:war:1.0-SNAPSHOT")
.withoutTransitivity().asSingle(WebArchive.class);
return retValue;
}
请注意,网上有很多针对简单 JAR 依赖项的修复(而不是在故障安全插件测试运行器中加载 Java EE WAR),这些修复几乎都是通过添加提到的编译器配置选项或 -g 来修复的在其他上下文中将
转换为 javac
。现有的解决方案不涉及可能比较特殊的com.sun.proxy.Proxy
。
最佳答案
当您调用 EJB 方法时,它总是通过代理。通常,此代理是在运行时生成的,并且不会有行号,因为它没有源代码。
从那里发生的事情取决于实现,需要安排(至少):
- 交易管理;
- 安全;
- 拦截器调用;
- 异常管理(方法中的 RuntimeExceptions 出现在 EJBExceptions 中)。
围绕您的实际方法调用。
如果您的 EJB 代码没有出现在堆栈跟踪中,则意味着在调用您的方法之前或调用之后出现了问题。
如果您显示实际的堆栈跟踪(包括“由 .. 引起”)和实际的异常,我们也许能够知道实际发生了什么。
我可以推测您正在调用有状态 EJB,而同一个 EJB 实例正处于另一个调用(来自较早的 HTTP 请求)中,因为我以前见过这种情况。有状态 EJB 强制执行单线程访问,这样您就不会遇到同步问题。所以第二个调用是抛出一个 Swing (有时称为抛出异常)。
关于java - 如何使运行 Arquillian 功能测试的 maven-failsafe-plugin 知道堆栈跟踪中的 EJB 行号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49590634/