8/27/2012

How to Run JBoss Jandex

Jandex is a tool that processes Java annotations within a directory or jar file, and saves the resulting metadata in an index file. This is similar to what a jar file index is to a classloader.

There are 3 ways to run jandex tool:

  1. java -jar command
  2. ant task
  3. jandex maven plugin
In JBoss AS7, jandex jar is located at $JBOSS_HOME/modules/org/jboss/jandex/main/jandex-1.0.3.Final.jar

To display the usage message,
java -jar jandex-1.0.3.Final.jar

Usage: jandex [-v] [-m] [-o file-name] <directory> | <jar>
-or-
jandex [-d] <index-file-name>
Options:
-v verbose output
-m modify directory or jar instead of creating an external index file
-o name the external index file file-name
-d dump the index file index-file-name

The default behavior, with no options specified, is to autogenerate an external index file

To scan a WAR file, adding the result to WAR's META-INF/jandex.idx (not WEB-INF/jandex.idx):
java -jar jandex-1.0.3.Final.jar -v -m /tmp/test.war

Indexed test.TestBean (2 annotations)
Indexed test.TestIF (0 annotations)
Indexed test.TestServlet (2 annotations)
Wrote META-INF/jandex.idx in 0.0710 seconds (3 classes, 4 annotations, 4 instances, 257 bytes)

To scan a WAR file and put result in the default result file in the same directory as the WAR file:
java -jar jandex-1.0.3.Final.jar /tmp/test.war

Wrote /tmp/test.war.idx in 0.0280 seconds (3 classes, 4 annotations, 4 instances, 257 bytes)

To view the content of an index file:
java -jar jandex-1.0.3.Final.jar -d /tmp/test.war.idx

Annotations:
javax.ejb.Stateless:
Class: test.TestBean
javax.ejb.EJB:
Field: test.TestIF test.TestServlet.testBean
javax.ejb.Local:
Class: test.TestBean
(value = [test.TestIF])
javax.servlet.annotation.WebServlet:
Class: test.TestServlet
(urlPatterns = ["/*"])
Subclasses:
javax.servlet.http.HttpServlet:
test.TestServlet
java.lang.Object:
test.TestBean
test.TestIF

Read test.war.idx in 0.0030 seconds

To scan a directory and save the result in a custom output file (-o option currently does not work with jar file input):
java -jar jandex-1.0.3.Final.jar -v -o /tmp/ann.dat $HOME/ws/test/

Indexed test.TestBean (2 annotations)
Indexed test.TestIF (0 annotations)
Indexed test.TestServlet (2 annotations)
Wrote /tmp/ann.dat in 0.0180 seconds (3 classes, 4 annotations, 4 instances, 257 bytes)

jandex.jar comes with an ant task, org/jboss/jandex/JandexAntTask. To run jandex with ant, first create a build.xml:
<?xml version="1.0"?>
<project name="test" default="jandex.modify" basedir=".">
<property environment="env" />
<taskdef name="jandex" classname="org.jboss.jandex.JandexAntTask"
classpath="${env.JBOSS_HOME}/modules/org/jboss/jandex/main/jandex-1.0.3.Final.jar" />

<target name="jandex.modify">
<jandex run="true" verbose="true" modify="true">
<fileset dir="${env.HOME}/ws/test" />
</jandex>
</target>

<target name="jandex.newjar">
<jandex run="true" verbose="true" newJar="true">
<fileset dir="${env.HOME}/ws/test" />
</jandex>
</target>
</project>
To process all "*.jar" files within a directory (recursively, adding the index file to the original jar:

ant jandex.modify

To process all "*.jar" files within a directory (recursively), and create a new index jar file (a jar file that only contains the generated index: META-INF/jandex.idx) for each source jar:

ant jandex.newjar

JandexAntTask (at least this version) filters on file name "*.jar", so any other types of jar files (*.war, *.ear, *.rar, etc) will not be included.

Jandex maven plugin project page has all the source and usages. With this plugin, jandex processes application annotations directly at build time, instead of post-processing the archives as in the 2 other methods. I tried the basic usage by copying the plugin element to one of the quickstart project pom.xml. After running mvn clean install, I can see the console output showing jandex being invoked as part of process-classes phase:
[INFO] --- jandex-maven-plugin:1.0.1:jandex (make-index) @ jboss-as-ejb-in-war ---
[INFO]
[INFO] --- maven-resources-plugin:2.4.3:testResources (default-testResources) @ jboss-as-ejb-in-war ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
...
To verify the index has been generated into target/classes and packaged into war file:
ls -l target/classes/META-INF/jandex.idx

jar tvf target/jboss-as-ejb-in-war.war | grep jandex

289 Tue Aug 28 10:09:40 EDT 2012 WEB-INF/classes/META-INF/jandex.idx
In the above output jandex.idx seems to have been packaged into the wrong directory inside the WAR. It should be in META-INF/jandex.idx. Could be a bug in jandex plugin?

Jandex can be used on jars or directories of any java application classes or libraries. For instance, the following command runs jandex on JDK classes.jar:
sudo java -jar jandex-1.0.3.Final.jar $JAVA_HOME/../Classes/classes.jar

Wrote /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/../Classes/classes-jar.idx
in 2.4900 seconds (20723 classes, 36 annotations, 1381 instances, 678046 bytes)

ls -l $JAVA_HOME/../Classes/*idx
-rw-r--r-- 1 root wheel 678046 Aug 28 10:45 /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/../Classes/classes-jar.idx

2 comments:

Anna said...

Great and Useful Article.

Online Java Training

Java Online Training India

Java Online Course

Java EE course

Java EE training

Best Recommended books for Spring framework

Java Interview Questions








Java Course in Chennai

Java Online Training India

Vũ Diệu Linh said...

I enjoyed on reading your blog post. Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article. Please visit my website, Friv 4000 Games is where all the free friv games.
Friv 4000