全包的夸克本机反射配置

人气:496 发布:2022-10-16 标签: reflection native kotlin quarkus

问题描述

我正在构建本地Quarkus,并使用条纹SDK作为外部库。 为了支持条纹SDK,我需要创建反射-配置.json文件,并在应用程序属性quarkus.native.additional-build-args=-H:ReflectionConfigurationFiles=reflection-config.json

中进行设置

反射-config.json如下所示:

  {
    "name": "com.stripe.model.Customer",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.stripe.model.Customer$InvoiceSettings",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.stripe.model.StripeError",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.stripe.model.PaymentIntent",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  },
  {
    "name": "com.stripe.model.PaymentMethod",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  }....

等等。 它包含的类太多。 我的问题是,是否有一种方法可以设置整个套餐,而不是大量的课程? 例如:

  {
    "name": "com.stripe.model.*",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true
  }

未找到任何提及它的内容。

推荐答案

请参阅下面的更新。

我使用完全相同的用例以编程方式添加包的所有类以进行反射,而无需编写扩展。 我的目标是为反射添加jOOQ生成的DB类,这样我就可以在本地编译的Quarkus GraalVM映像中与RESTEasy Active Jackson一起使用它们。 因为有很多这样的类,所以我不想在空类上用@RegisterForReflection注释手动填充reflection-config.json或目标。

我将Quarkus2.7.0.Final (not io.quarkus.platform as it is not released yet)与Gradle 7.3.3配合使用,尝试了以下方法,但很遗憾不起作用。 但我想这只有在构建扩展时才有效

package com.example.restapi.graal;

import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.CombinedIndexBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.IndexView;

public class JooqReflectionProcessor {

    private static final String JOOQ_DB_REFLECT_CLASSES = "com\.example\.restapi\.db\..+\.tables\.(pojos|records)\..+";

    @BuildStep
    public void build(BuildProducer<ReflectiveClassBuildItem> reflectiveClass, CombinedIndexBuildItem indexBuildItem) {
        IndexView index = indexBuildItem.getIndex();
        for (ClassInfo clazz : index.getKnownClasses()) {
            if (clazz.name().toString().matches(JOOQ_DB_REFLECT_CLASSES)) {
                reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, clazz.name().toString()));
            }
        }
    }

}

更新:

它并不美观,但我最终编写了一个Gradle任务,该任务自动创建所需的带有@RegisterForReflection(targets = {...})注释的jOOQ反射类:

task writeJooqReflectionClass {
    DefaultSourceDirectorySet sourceSet = project.sourceSets.findByName('main').java

    File jooqSrcDir = sourceSet.srcDirs
        .stream()
        .filter { it.path.replace('\', '/').matches('.+src/generated/jooq/main') }
        .findFirst()
        .get()

    ArrayList<String> classesForReflection = sourceSet
        .filter {
            it.path.contains(jooqSrcDir.path) &&
                it.path.replace('\', '/').matches('.+tables/(pojos|records)/.+') &&
                it.path.endsWith('.java')
        }
        .collect { it.path.replaceAll('[\\|/]', '.').substring(jooqSrcDir.path.length() + 1).replace('.java', '.class') }

    Collections.sort(classesForReflection)

    File file = new File("${jooqSrcDir.path}/com/example/restapi/db", "JooqReflectionConfig.java")
    file.getParentFile().mkdirs()
    file.text = """
    package com.example.restapi.db;

    import io.quarkus.runtime.annotations.RegisterForReflection;

    @RegisterForReflection(targets = {
        ${String.join(',
        ', classesForReflection)}
    })
    public class JooqReflectionConfig {

    }
    """.stripIndent()
}

compileJava.dependsOn(writeJooqReflectionClass)

例如,生成类com.example.restapi.db.JooqReflectionConfig,内容为:

package com.example.restapi.db;

import io.quarkus.runtime.annotations.RegisterForReflection;

@RegisterForReflection(targets = {
    com.example.restapi.db.master.tables.pojos.TableA.class,
    com.example.restapi.db.master.tables.pojos.TableB.class,
    com.example.restapi.db.master.tables.records.TableA.class,
    com.example.restapi.db.master.tables.records.TableB.class,
    com.example.restapi.db.mdc.tables.pojos.TableC.class,
    com.example.restapi.db.mdc.tables.pojos.TableD.class,
    com.example.restapi.db.mdc.tables.records.TableC.class,
    com.example.restapi.db.mdc.tables.records.TableD.class
})
public class JooqReflectionConfig {

}

248

上一篇:JNI防范混淆

下一篇:加载Java原生文件库