abstract classes with @EJB annotation included in libraries will cause deployment failures for EAP 7.2

Solution Verified - Updated

Environment

  • Red Hat JBoss Enterprise Application Platform (EAP)
    • 7.2.0

Issue

  • Our application uses common libraries which contains abstract classes to be extended, if such classes include annotations like @EJB for injection the deployment will fail if the final ear/war or the server does not have an implementation of that EJB. The same application will deploy fine with EAP 7.1
ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC000001: Failed to start service jboss.deployment.unit."ejb31-Injection-web2.war".INSTALL: org.jboss.msc.service.StartException in service jboss.deployment.unit."ejb31-Injection-web2.war".INSTALL: WFLYSRV0153: Failed to process phase INSTALL of deployment "ejb31-Injection-web2.war"
	at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:151)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1738)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.execute(ServiceControllerImpl.java:1700)
	at org.jboss.msc.service.ServiceControllerImpl$ControllerTask.run(ServiceControllerImpl.java:1558)
	at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
	at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1985)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1487)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1378)
	at java.lang.Thread.run(Thread.java:748)
Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: WFLYEJB0406: No EJB found with interface of type 'org.jboss.wfink.injection.ServiceOneLocal' for binding org.jboss.wfink.injection.AbstractService/serviceOne
	at org.jboss.as.ejb3.deployment.processors.EjbInjectionSource.getResourceValue(EjbInjectionSource.java:90)
	at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.addJndiBinding(ModuleJndiBindingProcessor.java:254)
	at org.jboss.as.ee.component.deployers.ModuleJndiBindingProcessor.deploy(ModuleJndiBindingProcessor.java:185)
	at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:144)
	... 8 more
  • abstract classes causes deployment failure if there are injections points which can not resolved at runtime

Resolution

The issue Content from issues.jboss.org is not included.JBEAP-16576 will be fixed for the next possible release.

Unfortunately there is no simple workaround.
The way it can be hacked is as followed:

  • Create your common.jar
  • remove the abstract class(es) from your jar file using 'zip -d common.jar -d your/package/AbstractService.class
  • run jandex for that file, see this article for more information
    java -jar $EAP72/modules/system/layers/base/org/jboss/jandex/main/jandex-2.0.5.Final-redhat-1.jar common.jar
  • move the create file (here common-jar.idx) to a path where the build will pick it up for META-INF/jandex.idx
  • build the application
    the idx file should be in the common.jar/META-INF/jandex.idx

If the jar is included in a war/ear, the abstract classes will be ignored for annotation processing.
But the injection for the class which extend it will work.

Root Cause

The deployment processor will analyze the annotation of the embedded library and try to resolve the injection no matter whether there is a need of injection as the class is marked as abstract.
The issue is tracked by Content from issues.jboss.org is not included.JBEAP-16576

Example class:

public abstract class AbstractService {

    @EJB
    ServiceOneLocal serviceOne;

    public String getServiceOne() {
        return serviceOne.getOne();
    }

}

This class is included in a simple jar which is used by another deployment, in example

Archive:  target/ejb31-Injection-web2.war
  META-INF/MANIFEST.MF    
  WEB-INF/classes/...
  WEB-INF/lib/ejb31-Injection-common-1.0-SNAPSHOT.jar  

As long as there is no implementation for the interface ServiceOneLocal found the deployment will fail!

Components
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.