如何在 Quarkus 中为外部模块中的 类 创建 Jandex 索引
How to create a Jandex index in Quarkus for classes in a external module
首先,我有一个像这样的多模块 Maven 层次结构:
├── project (parent pom.xml)
│ ├── service
│ ├── api-library
那么现在问题来了:
我正在服务模块中编写 JAX-RS 端点,它使用 api-library 中的 类。
当我启动 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
模块中。
所以我想我需要将它们添加到 application.properties 中的 Jandex 索引依赖项中。
但是如何将 Jandex 索引依赖项添加到 quarkus 中?
Quarkus 自动索引主模块,但是,当您有包含 CDI bean、实体、序列化为 JSON 的对象的附加模块时,您需要显式索引它们。
有几个不同的(易于实施的)选项可以做到这一点。
使用 Jandex Maven 插件
只需将以下内容添加到附加模块 pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.jboss.jandex</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>1.2.2</version>
<executions>
<execution>
<id>make-index</id>
<goals>
<goal>jandex</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
如果您的依赖项在项目外部并且您想一劳永逸地构建索引,这是最有益的选择。
使用 Gradle Jandex 插件
如果您使用的是 Gradle,可以使用第三方插件生成 Jandex 索引:https://github.com/kordamp/jandex-gradle-plugin .
添加空 META-INF/beans.xml
如果在附加模块 src/main/resources
中添加空 META-INF/beans.xml
文件,类 也将被索引。
类 将由 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>
是您选择的名称,用于标识您的依存关系。
编辑 (11/02/2020)
现在,在我的微服务中,我广泛使用 RegisterForReflection
注释中的 targets
属性。
根据文档,这是 属性 的解释:
/**
* 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.
*/
这在基于 quarkus 的项目上运行良好,并且可以在您想要注册少量 POJO 进行反射时处理基本情况。 RegisterForReflection
注解会自行注册 POJO,但不会注册 POJO 方法中的 return 类型。
更高级的方法是使用 @AutomaticFeature
注释 here. I am using it with Reflections Library and with custom made utility wrapper: 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 回答中所述,但是我的第三方 class (EpAutomationRs) 没有未在本机模式下注册反射。
所以我最终得到了注册它的快速而肮脏的解决方案(见下文)。
我创建了一个未使用的 REST JSON 端点,它 return 是 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();
}
对于gradle用户,您可以在您依赖的模块build.gradle中使用this插件。
首先,我有一个像这样的多模块 Maven 层次结构:
├── project (parent pom.xml)
│ ├── service
│ ├── api-library
那么现在问题来了:
我正在服务模块中编写 JAX-RS 端点,它使用 api-library 中的 类。
当我启动 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
模块中。
所以我想我需要将它们添加到 application.properties 中的 Jandex 索引依赖项中。
但是如何将 Jandex 索引依赖项添加到 quarkus 中?
Quarkus 自动索引主模块,但是,当您有包含 CDI bean、实体、序列化为 JSON 的对象的附加模块时,您需要显式索引它们。
有几个不同的(易于实施的)选项可以做到这一点。
使用 Jandex Maven 插件
只需将以下内容添加到附加模块 pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.jboss.jandex</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>1.2.2</version>
<executions>
<execution>
<id>make-index</id>
<goals>
<goal>jandex</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
如果您的依赖项在项目外部并且您想一劳永逸地构建索引,这是最有益的选择。
使用 Gradle Jandex 插件
如果您使用的是 Gradle,可以使用第三方插件生成 Jandex 索引:https://github.com/kordamp/jandex-gradle-plugin .
添加空 META-INF/beans.xml
如果在附加模块 src/main/resources
中添加空 META-INF/beans.xml
文件,类 也将被索引。
类 将由 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>
是您选择的名称,用于标识您的依存关系。
编辑 (11/02/2020)
现在,在我的微服务中,我广泛使用 RegisterForReflection
注释中的 targets
属性。
根据文档,这是 属性 的解释:
/**
* 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.
*/
这在基于 quarkus 的项目上运行良好,并且可以在您想要注册少量 POJO 进行反射时处理基本情况。 RegisterForReflection
注解会自行注册 POJO,但不会注册 POJO 方法中的 return 类型。
更高级的方法是使用 @AutomaticFeature
注释 here. I am using it with Reflections Library and with custom made utility wrapper: 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 回答中所述,但是我的第三方 class (EpAutomationRs) 没有未在本机模式下注册反射。 所以我最终得到了注册它的快速而肮脏的解决方案(见下文)。 我创建了一个未使用的 REST JSON 端点,它 return 是 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();
}
对于gradle用户,您可以在您依赖的模块build.gradle中使用this插件。