Как создать индекс Jandex в Quarkus для классов во внешнем модуле
Прежде всего, у меня есть многомодульная иерархия Maven, например:
├── project (parent pom.xml)
│ ├── service
│ ├── api-library
Итак, теперь к проблеме:
Я пишу JAX-RS Endpoint в сервисном модуле, который использует классы в API-библиотеке.
Когда я начинаю quarkus, я получаю это предупреждение:
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.
Это к занятиям com.example.Fruit
а также com.example.Car
расположены в api-library
модуль.
Поэтому я думаю, что мне нужно добавить их в индексную зависимость Jandex в application.properties.
Но как я могу добавить индексные зависимости Jandex в quarkus?
1 ответ
Quarkus автоматически индексирует основной модуль, но, когда у вас есть дополнительные модули, содержащие компоненты CDI, сущности, объекты, сериализованные как JSON, вам необходимо явно проиндексировать их.
Для этого есть несколько различных (простых в реализации) вариантов.
Использование плагина Jandex Maven
Просто добавьте следующее в ваш pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.jboss.jandex</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>1.0.5</version>
<executions>
<execution>
<id>make-index</id>
<goals>
<goal>jandex</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Это наиболее выгодный вариант, если ваша зависимость является внешней по отношению к вашему проекту, и вы хотите создать индекс раз и навсегда.
Добавление пустого META-INF/beans.xml
Если вы добавите пустой META-INF/beans.xml
файл в вашем src/main/resources
, классы также будут проиндексированы.
Классы будут проиндексированы самим Quarkus.
Индексирование других зависимостей
Если вы не можете изменить зависимость (например, подумайте о сторонней зависимости), вы все равно можете проиндексировать ее, добавив запись в свой application.properties
:
quarkus.index-dependency.<name>.group-id=
quarkus.index-dependency.<name>.artifact-id=
quarkus.index-dependency.<name>.classifier=(this one is optional)
с <name>
будучи именем, вы выбираете, чтобы определить свою зависимость.
Изменить (02.11.2020)
Сейчас в своих микросервисах я широко использую targets
собственность от RegisterForReflection
аннотация. Это объяснение свойства согласно документации:
/**
* 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.
*/
Это отлично работает с проектами на основе кваркуса и может обрабатывать базовые случаи, когда вы хотите зарегистрировать несколько POJO для отражения. ВRegisterForReflection
аннотация зарегистрирует POJO самостоятельно, но не будет регистрировать типы, возвращаемые из методов POJO.
Более продвинутый способ - использовать @AutomaticFeature
аннотацию, как описано здесь. Я использую его с библиотекой отражений и с пользовательской оболочкой утилиты: ReflectUtils
Теперь я могу выполнять более сложные задачи:
@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);
}
}
Первоначальный ответ
Я попытался добавить индекс Jandex, добавить beans.xml, а также для индексирования других зависимостей, как описано в ответе @emre-iÅŸÄ ± k, однако мой сторонний класс (EpAutomationRs) не был зарегистрирован для отражения в собственном режиме. В итоге я нашел быстрое и грязное решение для его регистрации (см. Ниже). Я создал неиспользуемую конечную точку REST JSON, которая возвращает класс.
/**
* 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();
}
Для пользователей Gradle вы можете использовать этот плагин в build.gradle модуля, от которого вы зависите.