Tout d'abord, j'ai une hiérarchie maven multi-module comme ça:
├── project (parent pom.xml)
│ ├── service
│ ├── api-library
Alors maintenant, le problème:
J'écris un point de terminaison JAX-RS dans le module de service qui utilise des classes dans l'api-library.
Lorsque je démarre quarkus, je reçois cet avertissement:
13:01:18,784 WARN [io.qua.dep.ste.ReflectiveHierarchyStep] Unable to properly register the hierarchy of the following classes for reflection as they are not in the Jandex index:
- com.example.Fruit
- com.example.Car
Consider adding them to the index either by creating a Jandex index for your dependency or via quarkus.index-dependency properties.
Ces deux classes com.example.Fruit
et com.example.Car
sont situés dans le api-library
module.
Je pense donc que je dois les ajouter à la dépendance d'index Jandex dans le fichier application.properties.
Mais comment puis-je ajouter des dépendances d'index Jandex dans quarkus?
Quarkus indexe automatiquement le module principal mais, lorsque vous avez des modules supplémentaires contenant des beans CDI, des entités, des objets sérialisés en JSON, vous devez les indexer explicitement.
Il existe deux options différentes (faciles à mettre en œuvre) pour le faire.
tilisation du plugin Jandex Maven
Ajoutez simplement ce qui suit à votre pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.jboss.jandex</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>1.0.7</version>
<executions>
<execution>
<id>make-index</id>
<goals>
<goal>jandex</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
C'est l'option la plus avantageuse si votre dépendance est externe à votre projet et que vous souhaitez construire l'index une fois pour toutes.
Ajout d'un META-INF/beans.xml vide
Si vous ajoutez un fichier META-INF/beans.xml
Vide dans votre src/main/resources
, Les classes seront également indexées.
Les classes seront indexées par Quarkus lui-même.
Indexation d'autres dépendances
Si vous ne pouvez pas modifier la dépendance (pensez à une dépendance tierce, par exemple), vous pouvez toujours l'indexer en ajoutant une entrée à votre application.properties
:
quarkus.index-dependency.<name>.group-id=
quarkus.index-dependency.<name>.artifact-id=
quarkus.index-dependency.<name>.classifier=(this one is optional)
<name>
étant un nom que vous choisissez pour identifier votre dépendance.
Pour les utilisateurs gradle, vous pouvez utiliser le plugin this dans le build.gradle du module dont vous dépendez.
Maintenant, dans mes microservices, j'utilise largement la propriété targets
de l'annotation RegisterForReflection
. Voici l'explication de la propriété selon la 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.
*/
Cela fonctionne très bien sur les projets basés sur quarkus et peut gérer les cas de base lorsque vous souhaitez enregistrer une poignée de POJO pour réflexion. L'annotation RegisterForReflection
enregistrera le POJO par lui-même, mais ne va pas enregistrer les types de retour des méthodes de POJO.
Un moyen plus avancé consiste à utiliser @AutomaticFeature
annotation comme décrit ici . Je l'utilise avec Bibliothèque de réflexions et avec un wrapper utilitaire personnalisé: ReflectUtils
Maintenant, je peux faire des tâches plus complexes:
@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);
}
}
J'ai essayé d'ajouter un index Jandex, d'ajouter beans.xml et également d'indexer d'autres dépendances comme décrit dans la réponse @ emre-işık, mais ma classe tierce (EpAutomationRs) n'a pas été enregistrée pour la réflexion en mode natif. Je me suis donc retrouvé avec une solution rapide et sale pour l'enregistrer (voir ci-dessous). J'ai créé un point de terminaison REST JSON inutilisé qui renvoie la classe.
/**
* 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();
}