java - 如何使运行 Arquillian 功能测试的 maven-failsafe-plugin 知道堆栈跟踪中的 EJB 行号

标签 java maven jakarta-ee stack-trace jboss-arquillian

我正在使用 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/

相关文章:

java - 如何在类里面支持 println?

java - 应用程序运行时消息包存储在哪里(内存或磁盘)?

java - %USERPROFILE% 下的 Eclipse Maven 本地存储库设置

maven - 是否可以针对 Hadoop 2.5.1 构建 Apache Spark

java - 使用 servlet 来管理状态?

java - 重定向主页中的所有页面

java - 是否有理由在 Java EE 的 @Webservice(.....) 注释中使用括号?

java - JAVA 中的非交互式密码 SSH

java - 哪种加密算法可用于加密存储在磁盘上的文件?

java - 尝试实现一个简单的 Jersey Rest 项目