How to create a jandex index for a jar so that JBoss EAP 6 or EAP 7 modules will scan a modules annotations

Solution Verified - Updated

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 annotations flag 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.

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.xml to 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.MF it 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.xml it is need to add a dependency entry with annotations="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.

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.