【问题标题】:Exception attempting to inject Remote ejb-ref when running multiple tests with Arquillian使用 Arquillian 运行多个测试时尝试注入远程 ejb-ref 的异常
【发布时间】:2012-10-09 18:12:12
【问题描述】:

我有许多使用“arquillian-glassfish-embedded-3.1”容器 (1.0.0.CR3) 使用 Arquillian (1.0.2.Final) 运行的测试类。

如果我单独运行任何测试类,它们会按预期运行,如果我尝试运行多个测试类 (TestSuite),则会遇到将 EJB 注入类的问题。

java.lang.RuntimeException: 无法注入成员

原因:java.lang.IllegalStateException:尝试注入远程 ejb-ref name=PackageManagerBean,Remote 3.x 接口=com.dcp.pkg.PackageManager 解析为模块测试中的应用内 EJB PackageManagerBean 的异常,ejb- link=PackageManagerBean,lookup=,mappedName=,jndi-name=PackageManagerBean,refType=会话到类 com.dcp.transmission.TransmissionManagerBeanTest: 在 SerialContext[myEnv={java.naming] 中查找 'java:comp/env/PackageManagerBean' 失败.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs =com.sun.enterprise.naming}

原因:com.sun.enterprise.container.common.spi.util.InjectionException: 尝试注入远程 ejb-ref name=PackageManagerBean,Remote 3.x interface =com.dcp.pkg.PackageManager 解析为内部的异常-app EJB PackageManagerBean in module test,ejb-link=PackageManagerBean,lookup=,mappedName=,jndi-name=PackageManagerBean,refType=Session 进入类 com.dcp.transmission.TransmissionManagerBeanTest:查找'java:comp/env/PackageManagerBean 失败' 在 SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl , java.naming.factory.url.pkgs=com.sun.enterprise.naming}

原因:javax.naming.NamingException:在 SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [根例外是 javax.naming。 NamingException:为“远程 ejb-ref name=PackageManagerBean,远程 3.x 接口=com.dcp.pkg.PackageManager 解析为模块测试中的应用程序内 EJB PackageManagerBean 解析 Ejb 的异常,ejb-link=PackageManagerBean,lookup=,mappedName= ,jndi-name=PackageManagerBean,refType=Session' 。用于查找的实际(可能是内部)远程 JNDI 名称是“PackageManagerBean#com.dcp.pkg.PackageManager”[根异常是 javax.naming.NamingException:在 SerialContext 中查找“PackageManagerBean#com.dcp.pkg.PackageManager”失败[ myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming .factory.url.pkgs=com.sun.enterprise.naming} [根异常是 javax.naming.NamingException: ejb ref resolution error for remote business interfacecom.dcp.pkg.PackageManager [根异常是 java.lang.IllegalArgumentException: 参数类型不匹配]]]]

原因:javax.naming.NamingException: Exception resolve Ejb for 'Remote ejb-ref name=PackageManagerBean,Remote 3.x interface =com.dcp.pkg.PackageManager 在模块测试中解析为应用内 EJB PackageManagerBean,ejb -link=PackageManagerBean,lookup=,mappedName=,jndi-name=PackageManagerBean,refType=Session'。用于查找的实际(可能是内部)远程 JNDI 名称是“PackageManagerBean#com.dcp.pkg.PackageManager”[根异常是 javax.naming.NamingException:在 SerialContext 中查找“PackageManagerBean#com.dcp.pkg.PackageManager”失败[ myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming .factory.url.pkgs=com.sun.enterprise.naming} [根异常是 javax.naming.NamingException: ejb ref resolution error for remote business interfacecom.dcp.pkg.PackageManager [根异常是 java.lang.IllegalArgumentException: 参数类型不匹配]]]

原因:javax.naming.NamingException:在 SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl. SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [根例外是 javax。 naming.NamingException:远程业务接口com.dcp.pkg.PackageManager 的ejb ref 解析错误[根异常是java.lang.IllegalArgumentException:参数类型不匹配]]

原因:javax.naming.NamingException:远程业务接口com.dcp.pkg.PackageManager的ejb ref解析错误[根异常是java.lang.IllegalArgumentException:参数类型不匹配]

原因:java.lang.IllegalArgumentException:参数类型不匹配

Package Manager Bean 定义如下:

@Stateless(mappedName = "PackageManagerBean")
@Remote({ PackageManager.class })
@Local({ PackageManagerLocal.class })
public class PackageManagerBean implements PackageManager {

}

包管理器被注入到几个测试类中,如下例所示:

@RunWith(Arquillian.class)
public class TransmissionManagerBeanTest {

      @Deployment
      public static Archive<?> createDeployment() {
                WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war")
                                    .addPackages(true, TransmissionManager.class.getPackage(), Search.class.getPackage(), PackageManager.class.getPackage(), SiteManagerBean.class.getPackage())
                                    .addAsResource("test-persistence.xml", "META-INF/persistence.xml").addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
                return war;
      }

  @EJB
  TransmissionManager transmissionManager;

  @EJB
  PackageManager packageManager;

  @EJB
  SiteManager siteManager;

  @PersistenceContext
  EntityManager entityManager;

  @Inject
  UserTransaction userTransaction;

}

我似乎没有遇到任何其他 EJB 的问题。

有没有人知道问题出在哪里以及我如何才能让它发挥作用?

【问题讨论】:

  • 我不确定这是否有帮助,但PackageManagerBean 仅实现PackageManager 远程接口是否有原因?在类声明中省略本地接口的任何具体原因?此外,此测试是否适用于托管 GF 容器(如果是,则可能是由于类路径问题)?
  • 测试目前不适用于托管或远程 Glassfish 容器,但原因完全不同。测试抱怨我的 Entity bean 上的枚举之一是“不是序列化映射的有效类型。属性类型必须实现 Serializable 接口。”即使枚举确实实现了 Serializable。
  • 我还看到以下错误:DeploymentContext 不包含任何 EJB。检查存档以确保正确打包 /apps/glassfish3/glassfish/domains/domain1/applications/test。如果您使用 EJB 组件注释来定义 EJB,并且还使用了 ejb 或 Web 部署描述符,请确保部署描述符引用 Java EE 5 或更高版本的模式,并且元数据完整属性未设置为true,因此可以按预期处理组件注释。有关详细信息,请参阅 server.log。 [状态:CLIENT_ERROR 原因:错误请求]
  • 运行单类测试时出现此错误!

标签: ejb-3.1 jboss-arquillian


【解决方案1】:

据我所知,在每个测试类之间清理部署在嵌入式 Glassfish 容器中的资源似乎是一个问题。目前我不知道是 Arquillian、嵌入式 Glassfish 容器还是我的代码导致了问题。

我找到了解决方法。通过在它自己的 JVM 中运行每个测试类,我避免了上述问题。它确实增加了一些额外的开销,例如而不是为所有测试类重新使用嵌入式容器,容器被拆除并为每个测试类重新启动,但它确实允许我一次性运行所有单元测试。

我使用 maven 运行测试并使用以下 maven-surefire-plugin 配置来确保每个测试类都在其自己的 JVM 中运行:

&lt;configuration&gt;&lt;forkCount&gt;1&lt;/forkCount&gt;&lt;reuseForks&gt;false&lt;/reuseForks&gt;....&lt;/configuration&gt;

对于早于 2.14 的 maven-surefire-plugin 版本,您可以使用 forkMode=false

【讨论】:

  • 嵌入式容器有点复杂,因为从技术上讲,所有东西都在同一个类路径上(glassfish 实例在同一个万无一失的 JVM 中启动)。一般来说,我只推荐嵌入简单容器——CDI 或 EJB 独立,或者只是 servlet(因为它需要 WAR)。部署整个应用服务器。您想要分离 JVM,因为它们通常会扫描可部署的东西。结果,您可能最终在类路径上出现了重复项。恕我直言,Fork 是正确的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-27
  • 1970-01-01
  • 2015-03-17
  • 1970-01-01
  • 2014-09-22
  • 1970-01-01
相关资源
最近更新 更多