CDI在使用TomEE(或OpenEJB),Jetty和Selenium进行功能测试时出现问题



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

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

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

但是我有一些麻烦,让CDI在较新版本的Jetty和OpenEJB或TomEE中正常工作。我在互联网上找不到另一个与较新版本的框架相同的示例。我甚至不知道我是否真的需要Jetty来做这件事。

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

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

java.lang.IllegalStateException: Unable to access CDI

持久性.xml:

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

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

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

使用 TomEE7.0.3 和 Jetty 9.4,我可以让 CDI 只在 maven 依赖项中为 TomEE 更改 OpenEJB(奇怪!应该OpenEJB有CDI支持(。当我在服务器设置的中间进行调试时,此 CDI 有效,但是当程序点击 Web 应用程序时,发生错误,我正在尝试进行 EJB 查找:

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

第三次尝试:Jetty (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");

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

更改持久性中的属性.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 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>

坚持不懈.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(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

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

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

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

最新更新