30

首先,我有一个像这样的多模块 Maven 层次结构:

├── project (parent pom.xml)
│   ├── service
│   ├── api-library

所以现在解决问题:

我正在使用 API 库中的类的服务模块中编写 JAX-RS 端点。
当我启动 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.Fruitcom.example.Car位于api-library模块中。

所以我认为我需要将它们添加到 application.properties 中的 Jandex 索引依赖项中。

但是如何将 Jandex 索引依赖项添加到 quarkus 中?

4

3 回答 3

40

Quarkus 自动索引主模块,但是当您有包含 CDI bean、实体、序列化为 JSON 的对象的其他模块时,您需要显式索引它们。

有几个不同的(易于实施)选项可以做到这一点。

使用 Jandex Maven 插件

只需将以下内容添加到附加模块 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>

如果您的依赖项在您的项目之外并且您想一劳永逸地构建索引,这是最有益的选择。

使用 Gradle Jandex 插件

如果你使用 Gradle,有一个第三方插件允许生成 Jandex 索引:https ://github.com/kordamp/jandex-gradle-plugin 。

添加一个空的 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>名称来识别您的依赖关系。

于 2019-04-04T10:31:56.340 回答
1

编辑(2020 年 11 月 2 日)

现在在我的微服务中,我广泛使用注释中的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.
 */

这在基于 quarkus 的项目上运行良好,并且可以在您想要注册少量 ​​POJO 以进行反射时处理基本情况。注解会自己注册 POJO ,RegisterForReflection但不会注册 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();
}
于 2019-08-07T17:21:58.707 回答
0

对于 gradle 用户,你可以在你依赖的模块的 build.gradle 中使用这个插件。

于 2020-01-17T04:17:24.583 回答