How to create a jandex index for a jar so that JBoss EAP 6 or EAP 7 modules will scan a modules annotations
Environment
- Red Hat JBoss Enterprise Application Platform (EAP)
- 6.x
- 7.x
Issue
- How to create a jandex index for a jar so that JBoss EAP 6 modules will scan a modules annotations?
- I have a custom module in the modules directory, when I depend on the module I can see the classes, but the annotations are being ignored, how do I fix this?
- I use inheritance in my application and the superclass is located in a module, it seems that the annotations are not scanned here
- The @PostConstruct method of an abstract superclass within a static JBoss module is not called.
- When the
annotationsflag is added to a module in EAP 7 the deployment time of my application increases and a lot of CPU is consumed.
- To integrate with azure ad, developers changed Spring Boot version of application to latest as azure ad is using newer version of spring security. When the new built war file is deployed in JBoss EAP 6.4.19, the application is failing. The JBoss EAP starts up with several exceptions and warnings like mentioned below :
12:51:50,205 WARN [org.jboss.as.server.deployment] (MSC service thread 1-1) JBAS015852: Could not index class module-info.class at /content/example.war/WEB-INF/lib/azure-core-1.2.0.jar: java.lang.IllegalStateException: Unknown tag! pos=4 poolCount = 87
at org.jboss.jandex.Indexer.processConstantPool(Indexer.java:673) [jandex-1.2.5.Final-redhat-1.jar:1.2.5.Final-redhat-1]
at org.jboss.jandex.Indexer.index(Indexer.java:707) [jandex-1.2.5.Final-redhat-1.jar:1.2.5.Final-redhat-1]
at org.jboss.as.server.deployment.annotation.ResourceRootIndexer.indexResourceRoot(ResourceRootIndexer.java:100) [jboss-as-server-7.5.19.Final-redhat-2.jar:7.5.19.Final-redhat-2]
at org.jboss.as.server.deployment.annotation.AnnotationIndexProcessor.deploy(AnnotationIndexProcessor.java:51) [jboss-as-server-7.5.19.Final-redhat-2.jar:7.5.19.Final-redhat-2]
at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:177) [jboss-as-server-7.5.19.Final-redhat-2.jar:7.5.19.Final-redhat-2]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:2064) [jboss-msc-1.1.7.SP1-redhat-1.jar:1.1.7.SP1-redhat-1]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1987) [jboss-msc-1.1.7.SP1-redhat-1.jar:1.1.7.SP1-redhat-1]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [rt.jar:1.8.0_191]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [rt.jar:1.8.0_191]
at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_191]
Resolution
NOTE 1: This will not work for modules added via the EE subsystem's global modules feature until EAP 6.3.0.GA due to Content from issues.jboss.org is not included.AS7-5651.
NOTE 2: Since EAP 7.0 there is an automatic scanning that searches for annotations in the static modules (using the annotations flag in the jboss-deployment-structure or MANIFEST.MF files as commented below).
1) Create a Jandex index for the jar
If building the jar from source, add the index at build time.
- For Maven follow the instructions for Content from github.com is not included.jandex-plugin
- For Ant use the Content from github.com is not included.Jandex Ant task
- If not building the jar or do not wish to alter the build, create a new
"index jar"to add to the module. Use theJandexjar to build the index, and then insert it into a new jar file like shown below
java -jar $JBOSS_HOME/modules/org/jboss/jandex/main/jandex-1.0.3.Final-redhat-1.jar $JAR_FILE
mkdir /tmp/META-INF
mv $JAR_FILE.idx /tmp/META-INF/jandex.idx
jar cf index.jar -C /tmp META-INF/jandex.idx
- Place the jar in the module directory and edit
module.xmlto add it to the resource roots. - or modify an existing jar to embed the index
java -jar $JBOSS_HOME/modules/org/jboss/jandex/main/jandex-1.0.3.Final-redhat-1.jar -m $JAR_FILE
2) Tell the module import to utilize the annotation index, so that annotation scanning can find the annotations.
There are two ways to do this, either using the MANIFEST.MF or using jboss-deployment-structure.xml.
- Using
MANIFEST.MFit needs to add a Dependencies entry, with annotations specified after the entry, for example:
Dependencies: com.my-module annotations
Note: if using CDI in a custom module, then users will also want to add meta-inf to make the META-INF/ directory visible to see the beans.xml.
Dependencies: com.my-module annotations meta-inf
- Using
jboss-deployment-structure.xmlit is need to add a dependency entry withannotations="true", for example:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<dependencies>
<module name="com.my-cdi-module" annotations="true"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
And if needs the META-INF of the custom module, then it would add meta-inf="import", for example:
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
<deployment>
<dependencies>
<module name="com.my-module" meta-inf="import" annotations="true"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
Root Cause
In EAP 6 JBoss's annotation scanning does not check classes from imported modules by default. This means that EJB/CDI interceptors whose classes are located in modules will not work correctly, since their annotations are not visible to the scanner. In general, the automatic scanning of modules can be a long and CPU consuming process that increases the deployment time. Therefore, for performance reasons, even in EAP 7 manual indexes creation is still recommended for large deployments.
The Jira Content from issues.jboss.org is not included.AS7-944 added the automatic scanning of modules in EAP 7.0. The current implementation in EAP 7 is an all or nothing if the index is added to a jar file inside the module no scanning at all is executed.
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.