【问题标题】:Problems with CDI in setup for functional testing with TomEE (or OpenEJB), Jetty and Selenium使用 TomEE(或 OpenEJB)、Jetty 和 Selenium 进行功能测试时设置 CDI 的问题
【发布时间】:2018-01-14 05:48:57
【问题描述】:

我正在尝试使用 Jetty、OpenEJB 和 WebApps 以编程方式设置环境来开发和运行 Selenium 测试。本文中描述的内容非常相似:http://tomee.apache.org/functional-testing-with-openejb,-jetty-and-selenium.html

这个设置很好,因为我可以通过IDE或Maven启动selenium测试,并使用相同的代码启动一个Server进行开发。

我看到这个设置使用旧版本的 Jetty (6.2) 和 EJB 3.0 中的未知 EJB 容器(称为 MyContainer)。现在我正在(或尝试做...)一个新项目中做同样的事情,它将在 Wildfly 10.1.0 中运行并通过 CDI (BeanManager) 进行 EJB 查找。

但是我在让 CDI 在较新版本的 Jetty 和 OpenEJB 或 TomEE 中正常工作时遇到了一些麻烦。我无法在 Internet 上找到与较新版本的框架相同的示例。我什至不知道我是否真的需要 Jetty 来做到这一点。

第一次尝试:Jetty(没有 jetty-jndi)+ OpenEJB + tomee.jpa.cdi=false

使用 OpenEJB 4.7.4 和 Jetty 9.4,当我运行代码 CDI.current().getBeanManager() 时:

java.lang.IllegalStateException: Unable to access CDI

persistence.xml:

<property name="tomee.jpa.cdi" value="false" />

Obs.:beans.xml 文件在所有尝试中都在我的 webapp 的 WEB-INF 目录中。

第二次尝试:Jetty(没有 jetty-jndi)+ TomEE + tomee.jpa.cdi=false

使用 TomEE 7.0.3 和 Jetty 9.4,我可以让 CDI 仅在 Maven 依赖项中更改 TomEE 的 OpenEJB(奇怪!据说 OpenEJB 支持 CDI)。当我在服务器设置中间进行调试时,此 CDI 有效,但是当程序运行 webapp 时,在我尝试进行 EJB 查找时发生错误:

"On a thread without an initialized context nor a classloader mapping a deployed app"

第三次尝试:Jetty(使用 jetty-jndi)+ TomEE 或 OpenEJB + tomee.jpa.cdi=false

EJB 容器启动但 Jetty 服务器无法启动,因为找不到 java:comp/env/

javax.naming.NameNotFoundException: Name "comp/env" not found

添加代码:

Configuration.ClassList classlist = Configuration.ClassList.setServerDefault(server);
classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration",
                    "org.eclipse.jetty.plus.webapp.EnvConfiguration",
                    "org.eclipse.jetty.plus.webapp.PlusConfiguration");

第四次尝试:Jetty(没有 jetty-jndi)+ TomEE + tomee.jpa.factory.lazy=true

更改persistence.xml中的属性:

<property name="tomee.jpa.factory.lazy" value="true" />

EJB 容器启动并且 CDI.current() 存在,但是当我尝试使用代码执行一些 SQL 之后:

@PersistenceContext(unitName="my-pu")
private EntityManager em;

//method
Session session = em.unwrap(Session.class);
session.doWork(new Work() {
    @Override
    public void execute(Connection connection) throws SQLException {
        try (Statement statement = connection.createStatement()) {
            statement.executeUpdate(sql);
            connection.commit();
        }
    }
});

系统在Session session = em.unwrap(Session.class); 停了很多时间。之后,出现了很多错误(Unable to build Hibernate SessionFactoryCould not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister)并且在stacktrace的末尾:

Caused by: javax.ejb.ConcurrentAccessTimeoutException: No instances available in Stateless Session Bean pool.  Waited 30 SECONDS

问题

那么,可能是类路径问题吗?在从旧的 EJB 容器中删除一些依赖项后,我已经遇到了 TomEE CDI 的一些问题。我已经阅读了 CDI 问题,原因是与 cdi-api 依赖项相关的错误导入。

如果有人有一些与我非常不同(且更简单)的想法来使这种环境发挥作用,那么也欢迎。

代码的一些相关部分

Maven 依赖 JavaEE API:

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
</dependency>

Maven 依赖 CDI API:

<dependency>
    <groupId>javax.enterprise</groupId>
    <artifactId>cdi-api</artifactId>
    <version>1.2</version>
    <scope>provided</scope>
</dependency>

Maven 依赖 OpenEJB 4.7.4:

<dependency>
        <groupId>org.apache.openejb</groupId>
        <artifactId>openejb-core</artifactId>
        <version>4.7.4</version>
</dependency>

Maven 依赖 TomEE 7.0.3:

<dependency>
    <groupId>org.apache.tomee</groupId>
    <artifactId>openejb-core</artifactId>
    <version>7.0.3</version>
</dependency>

Maven 依赖 Jetty:

    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-server</artifactId>
        <version>9.4.6.v20170531</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-webapp</artifactId>
        <version>9.4.6.v20170531</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-plus</artifactId>
        <version>9.4.6.v20170531</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-jndi</artifactId>
        <version>9.4.6.v20170531</version>
    </dependency>

persistence.xml

<!-- I uncomment only one of this properties each time -->
<!-- <property name="tomee.jpa.factory.lazy" value="true" />-->
<property name="tomee.jpa.cdi" value="false" />

ServiceLocator 查找代码 (ServiceLocator.lookup(CrudService.class)):

@Override
public Object lookup(Class<?> type, Annotation... annotations) throws NamingException {
    BeanManager manager = CDI.current().getBeanManager();
    Iterator<Bean<?>> beans = manager.getBeans(type, annotations).iterator();

    if (!beans.hasNext()) {
        throw new NamingException("CDI BeanManager cannot find an instance of requested type " + type.getName());
    }
    Bean<?> bean = beans.next();
    CreationalContext<?> ctx = manager.createCreationalContext(bean);
    return manager.getReference(bean, type, ctx);
}

创建 EJBContainer:

EJBContainer.createEJBContainer(props).getContext(); //nothing special in the props

【问题讨论】:

    标签: ejb jetty cdi apache-tomee openejb


    【解决方案1】:

    也许只使用 org.apache.tomee javaee api 而不是首先使用 javax 规范 jars。

    然后您可能需要一个强制 jndi 系统属性的类 - 遗憾的是在运行时 - 首先设置 openejb 包,因为 jetty jndi 安装程序会破坏现有设置,假设它是单独的。

    也可以分享您的日志或项目,这有助于了解发生了什么。

    【讨论】:

      猜你喜欢
      • 2013-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-14
      • 1970-01-01
      • 1970-01-01
      • 2018-12-02
      相关资源
      最近更新 更多