Problems with CDI in setup for functional testing with TomEE (or OpenEJB), Jetty and Selenium

≡放荡痞女 提交于 2019-12-11 08:45:24

问题


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.

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.

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

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.

First attempt: Jetty (without jetty-jndi) + OpenEJB + tomee.jpa.cdi=false

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:

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

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

Second attempt: Jetty (without jetty-jndi) + TomEE + tomee.jpa.cdi=false

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"

Third attempt: Jetty (with jetty-jndi) + TomEE or OpenEJB + tomee.jpa.cdi=false

EJB Container starts but Jetty server can't start because not found java:comp/env/.

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

Code added:

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");

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" />

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();
        }
    }
});

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

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.

Some relevant parts of the code

Maven dependency JavaEE API:

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

Maven dependency CDI API:

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

Maven dependency OpenEJB 4.7.4:

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

Maven dependency TomEE 7.0.3:

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

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

<!-- 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 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);
}

Create EJBContainer:

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

回答1:


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

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.



来源:https://stackoverflow.com/questions/45538143/problems-with-cdi-in-setup-for-functional-testing-with-tomee-or-openejb-jetty

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!