使用TomEE(或OpenEJB),Jetty和Selenium

时间:2017-08-07 01:11:11

标签: ejb jetty cdi tomee openejb

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

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

我看到这个设置使用旧版本的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)并且在堆栈跟踪结束时出现:

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

问题

那么,可能是类路径问题?我已经遇到了TomEE CDI的一些问题,这些问题在从旧的EJB容器中删除了一些依赖项之后得到了解决。我已经读过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

1 个答案:

答案 0 :(得分:0)

也许只使用org.apache.tomee javaee api而不使用javax spec jars。

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

也可以分享你的日志或项目,它可以帮助你知道会发生什么。