本文介绍了使用TomEE(或OpenEJB),Jetty和Selenium进行功能测试的设置中的CDI问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to setup programatically an environment with Jetty, OpenEJB and WebApps to development and run Selenium tests. Something very similar described in this article: http://tomee.apache.org/functional-testing-with-openejb,-jetty-and-selenium.html.

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

This setup is very good, because I can start selenium test by the IDE or Maven, and use the same code to start a Server for development.

我看到此安装程序使用旧版本的Jetty(6.2)和EJB 3.0中的未知EJB容器(称为MyContainer)工作.现在,我正在(或尝试做...)一个新项目中的同一件事,该项目将在Wildfly 10.1.0中运行,并通过CDI(BeanManager)进行EJB查找.

I saw this setup working using an old version of Jetty (6.2) and with an unknown EJB container (called MyContainer) in EJB 3.0. Now I'm doing (or tryingto do ...) the same thing in a newer project, that will run in Wildfly 10.1.0 and do EJB lookups by CDI (BeanManager).

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

But I have some troubles to put CDI to work correctly in the newer versions of Jetty and OpenEJB or TomEE. I can't find another examples on Internet to the same thing with newer versions of the frameworks. I don't even know if I really need Jetty to do that.

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

Using the OpenEJB 4.7.4 and Jetty 9.4, when I run the code CDI.current().getBeanManager() results in:

java.lang.IllegalStateException: Unable to access CDI

persistence.xml:

persistence.xml:

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

不好.:所有尝试中,beans.xml文件都位于我的Web应用程序的WEB-INF目录中.

Obs.: The beans.xml file is in the WEB-INF directory of my webapp in all attempts.

使用TomEE 7.0.3和Jetty 9.4,我能够使CDI仅在maven依赖项中更改TomEE的OpenEJB(很奇怪!假设OpenEJB具有CDI支持).当我在服务器设置的中间进行调试时,此CDI可以工作,但是当程序进入Web应用程序时,发生错误,我正在尝试进行EJB查找:

Using TomEE 7.0.3 and Jetty 9.4, I'm able to have CDI only changing OpenEJB for TomEE in maven dependency (weird! It's supposed that OpenEJB have CDI support). This CDI works when I'm debugging in the middle of the Server setup, but when the program hit the webapp, occur an error whem I'm trying to made a EJB lookup:

"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中的属性:

Fourth attempt: Jetty (without jetty-jndi) + TomEE + tomee.jpa.factory.lazy=true

Change the property in persistence.xml:

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

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

The EJB container started and CDI.current() exists, but when I try to execute some SQLs after that with the code:

@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):

The system stops a lot of time in Session session = em.unwrap(Session.class);. After that, a lot of errors appear (Unable to build Hibernate SessionFactory, Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister) and at the end of the stacktrace:

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

问题

那么,这可能是类路径问题吗?我已经对TomEE CDI遇到了一些问题,这些问题从旧的EJB容器中删除了一些依赖关系后就得到了解决.我已经读到有关CDI问题的信息,原因是原因是与cdi-api依赖项相关的导入错误.

Question

So, could be a classpath problem? I already had some problems with TomEE CDI that was resolved after remove some of dependencies from the old EJB container. I already read about CDI problems that the cause was wrong imports related with cdi-api dependency.

如果某人的想法与我的想法大相径庭(且更简单),可以使这种环境正常工作,

If someone has some very different (and simpler) idea than mine to made this kind of environment work, it's welcome too.

Maven依赖JavaEE API:

Maven dependency JavaEE API:

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

Maven依赖CDI API:

Maven dependency CDI API:

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

Maven依赖OpenEJB 4.7.4:

Maven dependency 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:

Maven dependency TomEE 7.0.3:

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

Maven依赖码头:

Maven dependency 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

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)):

ServiceLocator lookup code (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:

Create EJBContainer:

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

推荐答案

也许仅使用org.apache.tomee javaee api,而无需首先使用javax规范.

Maybe use org.apache.tomee javaee api only and no javax spec jars first.

然后,您需要一个类来强制jndi系统属性-在运行时可悲-首先设置openejb软件包,因为Jetty jndi安装程序假定单独存在会破坏现有设置.

Then you can need a class forcing the jndi system property - sadly at runtime - to set openejb package first since jetty jndi installer breaks existing setup assuming it is alone.

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

Also maybe share your logs or project, it can help to know what happens.

这篇关于使用TomEE(或OpenEJB),Jetty和Selenium进行功能测试的设置中的CDI问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 18:52