我试图用编程方式设置Jetty,OpenEJB和WebApps来开发和运行Selenium测试的环境。本文中描述的东西非常相似:http://tomee.apache.org/functional-testing-with-openejb,-jetty-and-selenium.html。用TomEE(或OpenEJB),Jetty和Selen进行功能测试的设置中的CDI问题
这个设置非常好,因为我可以通过IDE或Maven启动硒测试,并使用相同的代码启动服务器进行开发。
我看到此设置使用旧版本的Jetty(6.2)以及EJB 3.0中的未知EJB容器(称为MyContainer)。现在我正在做一个新项目中的同样的事情(或者试图做...),它将在Wildfly 10.1.0中运行,并由CDI(BeanManager)执行EJB查找。
但是我有一些麻烦让CDI在更新版本的Jetty和OpenEJB或TomEE中正常工作。我无法在互联网上找到另一个与新版本框架相同的例子。我甚至不知道我是否真的需要Jetty来做到这一点。
首先尝试:码头(无码头-JNDI)+ OpenEJB的+ tomee.jpa.cdi =假
使用OpenEJB的4.7.4和码头9.4,当我运行代码CDI.current().getBeanManager()
结果:
java.lang.IllegalStateException: Unable to access CDI
的persistence.xml:
<property name="tomee.jpa.cdi" value="false" />
实验值:该beans.xml的文件是在所有的尝试中我的web应用程序的WEB-INF目录下。
第二次尝试:码头(不含码头-JNDI)+ TomEE + tomee.jpa.cdi =假
使用TomEE 7.0.3和Jetty 9.4,我能有CDI仅在改变为OpenEJB的TomEE Maven依赖(奇怪!它应该是OpenEJB有CDI支持)。这CDI的作品,当我在服务器设置的中间正在调试,但是当程序打web应用程序,发生whem我试图做一个EJB查找错误:
"On a thread without an initialized context nor a classloader mapping a deployed app"
第三次尝试:码头( with 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");
第四次尝试:码头(不含码头-JNDI)+ TomEE + tomee.jpa.factory.lazy =真
更改属性在persistence.xml中:
<property name="tomee.jpa.factory.lazy" value="true" />
EJB容器启动并且CDI.current()存在,但是当我尝试执行某些SQL之后h代码:
@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 SessionFactory
,Could 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
问题
所以,可能是一个classpath的问题? 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的依赖性码头:
<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