如何在Spring Boot中测试EJB-由于模块信息

时间:2019-04-04 10:19:23

标签: java spring-boot ejb openejb

我目前正在将一个应用程序从Spring Boot 1.X升级到2.X。应用程序中的测试之一是在@SpringBootTest下使用OpenEJB测试无状态远程EJB。由于在Spring 5中已经删除了对SpringBeanAutowiringInterceptor的支持,因此我现在面临着重写逻辑并对其进行测试的任务,这就是问题所在: 我们在JDK 1.8和 openejb (4.7.4,用于初始化jndiContext的测试中)上运行,无法处理多发行版JAR,这是从升级到Spring Boot 2.X的依赖项(例如字节码和其他)。 OpenEJB尝试加载 META-INF / versions / 9 / module-info ,并在IllegalArgumentException上失败。 我还尝试将Glassfish用作加载程序,从OpenEJB切换到EJBcontainer,但我面临着其他问题(当前尝试解决的问题是jndContext中未设置无状态Bean-在DEBUG中进行了检查)。

我的问题是:是否有可能以某种方式迫使classloader或openejb忽略module-info,以便能够在JDK 1.8下使用classpath上的多版本jar来运行它?还是有一种方法可以将EJBContainer与glassfish-embedded-all结合使用,它目前不加载EJB,但至少加载无错误的上下文?我需要避免错误或使用另一种方法来测试无状态SpringBootTest中的Bean。

注意:我不想使用Arquillian

版本摘要:

  • JDK 1.8
  • spring-boot-starter-parent:2.1.3发布
  • openejb-core:4.7.4
  • 所有嵌入玻璃鱼的版本: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)

使用玻璃鱼的错误(可能指定了错误的模块?):

ERROR embedded [] []- EJB6005:No EJB modules found

测试课程的重要部分:

@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,并且会发生相同的错误

1 个答案:

答案 0 :(得分:0)

使用较新版本的openEJB-> Apache Tomee解决了问题,即使我使用的是JDK 1.8,Apache Tomee也使用asm6并支持JDK 1.9,但是由于Spring Boot 2依赖于多版本JARS,因此需要此支持。 使用的工件:

    <dependency>
        <groupId>org.apache.tomee</groupId>
        <artifactId>apache-tomee</artifactId>
        <version>8.0.0-M2</version>
        <scope>test</scope>
    </dependency>