javaspring-bootejbopenejb

How to test EJBs in Spring Boot - openejb cannot handle multi-release JARs because of module-info


I am currently upgrading one application from Spring Boot 1.X to 2.X. One of the tests in the application is testing Stateless remote EJB using OpenEJB under the @SpringBootTest. Since the support for SpringBeanAutowiringInterceptor has been dropped in Spring 5, I am now faced with a task to rewrite the logic and test it and here comes the problem: We are running on JDK 1.8 and openejb (4.7.4, which is used in the test to initialize jndiContext) cannot handle multi-release JARs which comes as a dependencies from upgrade to Spring Boot 2.X (for example byte-buddy and others). OpenEJB tries to load META-INF/versions/9/module-info and fails on IllegalArgumentException. I am also trying switch from OpenEJB to EJBcontainer along with glassfish as loader, but I am facing different issues (Stateless bean is not set in the jndContext - inspected in DEBUG), which I am currently trying to solve.

My question is: Is there any possibility to somehow force classloader or openejb to ignore module-info to be able to run it under JDK 1.8 with multi-release jars on classpath? Or is there a way to use EJBContainer with glassfish-embedded-all, which currently doesn't load the EJB but at least load the context without error? I need to avoid the error or use another way how to test Stateless Bean in SpringBootTest.

Note: I don't want to use Arquillian

Summary of versions:

Error using openEJB (module-info, multi-release JARs problem):

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 using glassfish (probably wrong MODULES specified?):

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

Important part of test 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");
}

Project structure (simplified - large project, cannot change):

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

UPDATE: Currently trying apache-tomee (1.7.5) instead of openejb-core sbut it uses also asm5 and the same error occurs


Solution

  • Problem solved using newer version openEJB -> Apache Tomee, which uses asm6 and supports JDK 1.9, even if I am using JDK 1.8, but because of multi-release JARS as dependencies from Spring Boot 2, this support is needed. Artifact used:

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