How to create a Jandex index in Quarkus for classes in a external module
Solution 1:
Quarkus automatically indexes the main module but, when you have additional modules containing CDI beans, entities, objects serialized as JSON, you need to explicitly index them.
There are a couple of different (easy to implement) options to do so.
Using the Jandex Maven plugin
Just add the following to the additional module pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.jboss.jandex</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>1.1.0</version>
<executions>
<execution>
<id>make-index</id>
<goals>
<goal>jandex</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
It's the most beneficial option if your dependency is external to your project and you want to build the index once and for all.
Using the Gradle Jandex plugin
If you are using Gradle, there is a third party plugin allowing to generate a Jandex index: https://github.com/kordamp/jandex-gradle-plugin .
Adding an empty META-INF/beans.xml
If you add an empty META-INF/beans.xml
file in the additional module src/main/resources
, the classes will also be indexed.
The classes will be indexed by Quarkus itself.
Indexing other dependencies
If you can't modify the dependency (think of a third-party dependency, for instance), you can still index it by adding an entry to your application.properties
:
quarkus.index-dependency.<name>.group-id=
quarkus.index-dependency.<name>.artifact-id=
quarkus.index-dependency.<name>.classifier=(this one is optional)
with <name>
being a name you choose to identify your dependency.
Solution 2:
Edit (11/02/2020)
Now in my microservices I am extensively using the targets
property from RegisterForReflection
annotation.
This is the property explanation according to the documentation:
/**
* Alternative classes that should actually be registered for reflection instead of the current class.
*
* This allows for classes in 3rd party libraries to be registered without modification or writing an
* extension. If this is set then the class it is placed on is not registered for reflection, so this should
* generally just be placed on an empty class that is not otherwise used.
*/
This works fine on quarkus based projects and can handle the basic cases when you want to register a handful POJOs for reflection. The RegisterForReflection
annotation will register the POJO by himself, but will not going to register the return types from POJO's methods.
More advanced way is to use @AutomaticFeature
annotation as described here. I am using it with Reflections Library and with custom made utility wrapper: ReflectUtils
Now I can do more complex tasks:
@AutomaticFeature
@RegisterForReflection(targets = {
com.hotelbeds.hotelapimodel.auto.convert.json.DateSerializer.class,
TimeDeserializer.class,
DateSerializer.class,
TimeSerializer.class,
RateSerializer.class,
})
public class HotelBedsReflection implements Feature {
public static Logger log = Utils.findLogger(Reflections.class);
@Override
public void beforeAnalysis(BeforeAnalysisAccess access) {
ReflectUtils.registerPackage(LanguagesRQ.class.getPackage().getName(), Object.class);
ReflectUtils.registerPackage(AvailabilityRQ.class.getPackage().getName(), Object.class);
ReflectUtils.registerPackage(Occupancy.class.getPackage().getName(), Object.class);
}
}
Initial Answer
I've tried to add Jandex index, to add beans.xml and also to Indexing other dependencies as described in @emre-işık answer, however my third party class (EpAutomationRs) wasn't registered for reflection in native mode. So I've ended up with quick and dirty solution for registering it (see below). I've created an unused REST JSON endpoint which returns the class.
/**
* the purpose of this method is to register for reflection EpAutomationRs class
*
* @return
*/
@GET
@Path(GET_EMPTY_RS)
@Produces(MediaType.APPLICATION_JSON)
public EpAutomationRs entry() {
return new EpAutomationRs();
}