如何在 Spring 引导中测试 EJB - 由于模块信息,openejb 无法处理多版本 JAR
How to test EJBs in Spring Boot - openejb cannot handle multi-release JARs because of module-info
我目前正在将一个应用程序从 Spring Boot 1.X 升级到 2.X。应用程序中的一项测试是在 @SpringBootTest 下使用 OpenEJB 测试无状态远程 EJB。由于 SpringBeanAutowiringInterceptor 的支持在 Spring 5 中被删除,我现在面临重写逻辑并测试它的任务,问题来了:
我们在 JDK 1.8 上 运行ning 和 openejb(4.7.4,在测试中用于初始化 jndiContext)无法处理随附的多版本 JAR作为升级到 Spring Boot 2.X 的依赖项(例如 byte-buddy 和其他)。 OpenEJB 尝试加载 META-INF/versions/9/module-info 并因 IllegalArgumentException 而失败。
我也在尝试从 OpenEJB 切换到 EJBcontainer 以及 glassfish 作为加载器,但我面临不同的问题(无状态 bean 未在 jndContext 中设置 - 在 DEBUG 中检查),我目前正在尝试解决这些问题。
我的问题是:是否有可能以某种方式强制 classloader 或 openejb 忽略模块信息以便能够 运行 它在 JDK 下1.8 在 class 路径上有多个版本的 jar?或者有没有一种方法可以将 EJBContainer 与 glassfish-embedded-all 一起使用,它目前不加载 EJB 但至少加载上下文没有错误? 我需要避免错误或使用另一种方法来测试SpringBootTest 中的无状态 Bean。
注意:我不想使用 Arquillian
版本汇总:
- JDK1.8
- spring-boot-starter-parent: 2.1.3.RELEASE
- openejb-核心:4.7.4
- glassfish-embedded-all: 5.1.0
使用 openEJB 时出错(模块信息、多版本 JAR 问题):
ERROR OpenEJB [] []- FATAL ERROR: Unknown error in Assembler. Please send the following stack trace and this message to users@tomee.apache.org :
java.lang.IllegalArgumentException
at org.apache.xbean.asm5.ClassReader.<init>(Unknown Source)
at org.apache.xbean.asm5.ClassReader.<init>(Unknown Source)
at org.apache.xbean.asm5.ClassReader.<init>(Unknown Source)
at org.apache.openejb.util.AnnotationFinder.readClassDef(AnnotationFinder.java:299)
at org.apache.openejb.util.AnnotationFinder.find(AnnotationFinder.java:164)
at org.apache.openejb.config.DeploymentLoader.checkAnnotations(DeploymentLoader.java:2008)
at org.apache.openejb.config.DeploymentLoader.discoverModuleType(DeploymentLoader.java:1891)
at org.apache.openejb.config.DeploymentsResolver.processUrls(DeploymentsResolver.java:389)
at org.apache.openejb.config.DeploymentsResolver.loadFromClasspath(DeploymentsResolver.java:302)
at org.apache.openejb.config.ConfigurationFactory.getModulesFromClassPath(ConfigurationFactory.java:664)
使用 glassfish 时出错(可能指定了错误的模块?):
ERROR embedded [] []- EJB6005:No EJB modules found
测试重要部分class:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {
CommonTestConfiguration.class,
DatabaseTestConfiguration.class,
PropositionServiceConfiguration.class,
BeanUtils.class,
PropositionRemoteServiceImpl.class,
PropositionRemoteService.class})
@DirtiesContext
public class PropositionRemoteServiceImplTest {
@Autowired
private AdminFacade adminFacade;
private PropositionRemoteService remoteService;
@Before
public void setUp() throws NamingException {
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory");
//props.put("openejb.deployments.classpath.exclude", ".*?module-info.*?");
Context jndiContext = new InitialContext(props);
remoteService = (PropositionRemoteService) jndiContext.lookup("PropositionRemoteServiceImplRemote");
// Map<String, Object> properties = new HashMap<>();
// properties.put(EJBContainer.MODULES, new File("target/classes"));
// EJBContainer ejbContainer = EJBContainer.createEJBContainer(properties);
// Context ctx = ejbContainer.getContext();
// remoteService = (PropositionRemoteService) ctx.lookup("PropositionRemoteServiceImplRemote");
}
项目结构(简化-大型项目,无法更改):
ude> root node module - pom
adapter> - node-module
ejb-adapter> node module
ejb-adapter-impl> node module containing Stateless bean used in test
test> node module
test-unit> node module where the Test class is defined and run
更新:
目前正在尝试 apache-tomee (1.7.5) 而不是 openejb-core s 但它也使用 asm5 并且发生相同的错误
使用较新版本的 openEJB -> Apache Tomee 解决了问题,它使用 asm6 并支持 JDK 1.9,即使我使用的是 JDK 1.8,但由于多版本 JARS 作为来自的依赖项Spring Boot 2,需要这个支持。
使用的工件:
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>apache-tomee</artifactId>
<version>8.0.0-M2</version>
<scope>test</scope>
</dependency>
我目前正在将一个应用程序从 Spring Boot 1.X 升级到 2.X。应用程序中的一项测试是在 @SpringBootTest 下使用 OpenEJB 测试无状态远程 EJB。由于 SpringBeanAutowiringInterceptor 的支持在 Spring 5 中被删除,我现在面临重写逻辑并测试它的任务,问题来了: 我们在 JDK 1.8 上 运行ning 和 openejb(4.7.4,在测试中用于初始化 jndiContext)无法处理随附的多版本 JAR作为升级到 Spring Boot 2.X 的依赖项(例如 byte-buddy 和其他)。 OpenEJB 尝试加载 META-INF/versions/9/module-info 并因 IllegalArgumentException 而失败。 我也在尝试从 OpenEJB 切换到 EJBcontainer 以及 glassfish 作为加载器,但我面临不同的问题(无状态 bean 未在 jndContext 中设置 - 在 DEBUG 中检查),我目前正在尝试解决这些问题。
我的问题是:是否有可能以某种方式强制 classloader 或 openejb 忽略模块信息以便能够 运行 它在 JDK 下1.8 在 class 路径上有多个版本的 jar?或者有没有一种方法可以将 EJBContainer 与 glassfish-embedded-all 一起使用,它目前不加载 EJB 但至少加载上下文没有错误? 我需要避免错误或使用另一种方法来测试SpringBootTest 中的无状态 Bean。
注意:我不想使用 Arquillian
版本汇总:
- JDK1.8
- spring-boot-starter-parent: 2.1.3.RELEASE
- openejb-核心:4.7.4
- glassfish-embedded-all: 5.1.0
使用 openEJB 时出错(模块信息、多版本 JAR 问题):
ERROR OpenEJB [] []- FATAL ERROR: Unknown error in Assembler. Please send the following stack trace and this message to users@tomee.apache.org :
java.lang.IllegalArgumentException
at org.apache.xbean.asm5.ClassReader.<init>(Unknown Source)
at org.apache.xbean.asm5.ClassReader.<init>(Unknown Source)
at org.apache.xbean.asm5.ClassReader.<init>(Unknown Source)
at org.apache.openejb.util.AnnotationFinder.readClassDef(AnnotationFinder.java:299)
at org.apache.openejb.util.AnnotationFinder.find(AnnotationFinder.java:164)
at org.apache.openejb.config.DeploymentLoader.checkAnnotations(DeploymentLoader.java:2008)
at org.apache.openejb.config.DeploymentLoader.discoverModuleType(DeploymentLoader.java:1891)
at org.apache.openejb.config.DeploymentsResolver.processUrls(DeploymentsResolver.java:389)
at org.apache.openejb.config.DeploymentsResolver.loadFromClasspath(DeploymentsResolver.java:302)
at org.apache.openejb.config.ConfigurationFactory.getModulesFromClassPath(ConfigurationFactory.java:664)
使用 glassfish 时出错(可能指定了错误的模块?):
ERROR embedded [] []- EJB6005:No EJB modules found
测试重要部分class:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {
CommonTestConfiguration.class,
DatabaseTestConfiguration.class,
PropositionServiceConfiguration.class,
BeanUtils.class,
PropositionRemoteServiceImpl.class,
PropositionRemoteService.class})
@DirtiesContext
public class PropositionRemoteServiceImplTest {
@Autowired
private AdminFacade adminFacade;
private PropositionRemoteService remoteService;
@Before
public void setUp() throws NamingException {
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory");
//props.put("openejb.deployments.classpath.exclude", ".*?module-info.*?");
Context jndiContext = new InitialContext(props);
remoteService = (PropositionRemoteService) jndiContext.lookup("PropositionRemoteServiceImplRemote");
// Map<String, Object> properties = new HashMap<>();
// properties.put(EJBContainer.MODULES, new File("target/classes"));
// EJBContainer ejbContainer = EJBContainer.createEJBContainer(properties);
// Context ctx = ejbContainer.getContext();
// remoteService = (PropositionRemoteService) ctx.lookup("PropositionRemoteServiceImplRemote");
}
项目结构(简化-大型项目,无法更改):
ude> root node module - pom
adapter> - node-module
ejb-adapter> node module
ejb-adapter-impl> node module containing Stateless bean used in test
test> node module
test-unit> node module where the Test class is defined and run
更新: 目前正在尝试 apache-tomee (1.7.5) 而不是 openejb-core s 但它也使用 asm5 并且发生相同的错误
使用较新版本的 openEJB -> Apache Tomee 解决了问题,它使用 asm6 并支持 JDK 1.9,即使我使用的是 JDK 1.8,但由于多版本 JARS 作为来自的依赖项Spring Boot 2,需要这个支持。 使用的工件:
<dependency>
<groupId>org.apache.tomee</groupId>
<artifactId>apache-tomee</artifactId>
<version>8.0.0-M2</version>
<scope>test</scope>
</dependency>