如何使 maven-failsafe-plugin 运行 Arquillian 功能测试知道堆栈跟踪中的 EJB 行号
How to make maven-failsafe-plugin running Arquillian functional tests aware of EJB line number in stacktrace
我正在 运行 使用 Arquillian 进行功能测试,它使用 Java EE 应用程序的完整 WAR,包括实体、EJB 接口和实现以及 webapp(JSF 页面和支持 bean) ) 安装到本地 Maven 存储库中,即测试非常接近集成测试。有时,我会遇到像
这样的堆栈跟踪
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
调用注入了 @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
中是否有一个选项 - 唯一似乎相关的是 warSourceIncludes
,但这取决于 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 导致 maven-checkstyle-plugin
为 target/generated-sources
执行并在生成的 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 代码没有出现在堆栈跟踪中,则意味着在调用您的方法之前或之后出现了错误。
如果您展示了实际的堆栈跟踪(包括 "Caused by ..")和实际的异常,我们或许能够告诉您实际发生了什么。
我可以推测您正在调用有状态 EJB,而同一个 EJB 实例正处于另一个调用(来自较早的 HTTP 请求)的中间,因为我以前见过这种情况。有状态 EJB 强制执行 single-threaded 访问,因此您不会遇到同步问题。所以第二个调用是 chucking a wobbly(有时称为抛出异常)。
我正在 运行 使用 Arquillian 进行功能测试,它使用 Java EE 应用程序的完整 WAR,包括实体、EJB 接口和实现以及 webapp(JSF 页面和支持 bean) ) 安装到本地 Maven 存储库中,即测试非常接近集成测试。有时,我会遇到像
这样的堆栈跟踪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
调用注入了 @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
中是否有一个选项 - 唯一似乎相关的是 warSourceIncludes
,但这取决于 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 导致 maven-checkstyle-plugin
为 target/generated-sources
执行并在生成的 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 代码没有出现在堆栈跟踪中,则意味着在调用您的方法之前或之后出现了错误。
如果您展示了实际的堆栈跟踪(包括 "Caused by ..")和实际的异常,我们或许能够告诉您实际发生了什么。
我可以推测您正在调用有状态 EJB,而同一个 EJB 实例正处于另一个调用(来自较早的 HTTP 请求)的中间,因为我以前见过这种情况。有状态 EJB 强制执行 single-threaded 访问,因此您不会遇到同步问题。所以第二个调用是 chucking a wobbly(有时称为抛出异常)。