CLOVER🍀

That was when it all began.

QuarkusのConfigurationを試す

これは、なにをしたくて書いたもの?

Quarkusを使った場合に、アプリケーションの設定をどう扱うのかをちょっと見てみようと。

結論から言うと、Configuration for MicroProfileを使用します。Quarkus上でConfiguration for MicroProfileを使う場合には、どんな感じに
なるのかをちょっと見てみましょう。

Configuration for MicroProfile

Configuration for MicroProfileとは、文字通りMicroProfileでのアプリケーションの設定に関するAPIを定めたものです。

Project – MicroProfile

QuarkusにおけるConfiguration for MicroProfileの実装は、こちらのライブラリです。

GitHub - smallrye/smallrye-config: SmallRye implementation of Eclipse MicroProfile Config

今回利用するQuarkus 0.14.0でのConfiguration for MicroProfileのバージョンは、1.3のようです。

ちなみに、Configuration for MicroProfileについては、以前にエントリを書いたことがあります。

Configuration for MicroProfileを試す - CLOVER🍀

この時は、Apache Geronimo Configを使用しました。

今回は、ちょっと簡単にQuarkusで試してみるとしましょう。

環境

今回の環境は、こちら。

$ java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-8u191-b12-2ubuntu0.18.04.1-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)


$ mvn -version
Apache Maven 3.6.1 (d66c9c0b3152b2e69ee9bac180bb8fcc8e6af555; 2019-04-05T04:00:29+09:00)
Maven home: $HOME/.sdkman/candidates/maven/current
Java version: 1.8.0_191, vendor: Oracle Corporation, runtime: /usr/lib/jvm/java-8-openjdk-amd64/jre
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "4.15.0-48-generic", arch: "amd64", family: "unix"

GraalVMも用意。

$ $GRAALVM_HOME/bin/java -version
openjdk version "1.8.0_202"
OpenJDK Runtime Environment (build 1.8.0_202-20190206132807.buildslave.jdk8u-src-tar--b08)
OpenJDK GraalVM CE 1.0.0-rc16 (build 25.202-b08-jvmci-0.59, mixed mode)

簡単なサンプルアプリケーションの作成

それでは、最初にQuarkusのプロジェクトを作成します。

$ mvn io.quarkus:quarkus-maven-plugin:0.14.0:create \
    -DprojectGroupId=org.littlewings \
    -DprojectArtifactId=quarkus-configuration \
    -DprojectVersion=0.0.1-SNAPSHOT \
    -Dextensions=resteasy-jsonb

RESTEasy JSONBもちょっと有効にしておきました。

Quarkusでの設定ファイルは、デフォルトで「application.properties」のようです。プロジェクト作成時に、中身のないファイルが
できているので、こちらに追記しましょう。
src/main/resources/application.properties

# Configuration file
# key = value

sample.greeting.message = Hello Quarkus!!

設定ファイルに追加した項目を利用する、設定用のクラスを作成します。
src/main/java/org/littlewings/quarkus/configuration/MyConfiguration.java

package org.littlewings.quarkus.configuration;

import javax.enterprise.context.ApplicationScoped;

import org.eclipse.microprofile.config.inject.ConfigProperty;

@ApplicationScoped
public class MyConfiguration {
    @ConfigProperty(name = "sample.greeting.message")
    String greetingMessage;

    @ConfigProperty(name = "sample.int.value", defaultValue = "10")
    int intValue;

    public String getGreetingMessage() {
        return greetingMessage;
    }

    public int getIntValue() {
        return intValue;
    }
}

@ConfigPropertyは、Configuration for MicroProfileのアノテーションです。ちなみに、ひとつ設定ファイルに記載していない項目が
ありますが、こちらにはデフォルト値を設定しています。

では、こちらを使用するJAX-RSリソースクラスを作成してみましょう。
src/main/java/org/littlewings/quarkus/configuration/SampleResource.java

package org.littlewings.quarkus.configuration;

import java.util.Properties;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.eclipse.microprofile.config.Config;

@Path("sample")
public class SampleResource {
    @Inject
    MyConfiguration myConfiguration;

    @Inject
    Config config;

    @GET
    @Path("greeting")
    @Produces(MediaType.TEXT_PLAIN)
    public String greeting() {
        return myConfiguration.getGreetingMessage();
    }

    @GET
    @Path("int-value")
    @Produces(MediaType.TEXT_PLAIN)
    public int intValue() {
        return myConfiguration.getIntValue();
    }

    @GET
    @Path("greeting-by-lookup")
    @Produces(MediaType.TEXT_PLAIN)
    public String greetingByLookup() {
        return config.getValue("sample.greeting.message", String.class);
    }

    @GET
    @Path("system-properties")
    @Produces(MediaType.APPLICATION_JSON)
    public Properties systemProperties() {
        return System.getProperties();
    }
}

使い方の例として、作成した設定用のクラスをインジェクションして利用する方法と

    @Inject
    MyConfiguration myConfiguration;

    @GET
    @Path("greeting")
    @Produces(MediaType.TEXT_PLAIN)
    public String greeting() {
        return myConfiguration.getGreetingMessage();
    }

Configuration for MicroProfileが提供するConfigインターフェースをインジェクションして、設定項目をルックアップする方法を書いています。

    @Inject
    Config config;

    @GET
    @Path("greeting-by-lookup")
    @Produces(MediaType.TEXT_PLAIN)
    public String greetingByLookup() {
        return config.getValue("sample.greeting.message", String.class);
    }

確認

では、こちらをビルドして

$ mvn package

確認してみましょう。

$ java -jar target/quarkus-configuration-0.0.1-SNAPSHOT-runner.jar

インジェクションしているものと、Configインターフェースから取得しているもの。

$ curl localhost:8080/sample/greeting
Hello Quarkus!!

$ curl localhost:8080/sample/greeting-by-lookup
Hello Quarkus!!

デフォルト値で動作しているもの。

$ curl localhost:8080/sample/int-value
10

OKですね。

Configuration for MicroProfileは、値をシステムプロパティや環境変数で上書きすることができます。

システムプロパティで上書きする場合。

$ java -Dsample.greeting.message='Hello World!' -Dsample.int.value=15 -jar target/quarkus-configuration-0.0.1-SNAPSHOT-runner.jar 

確認。

$ curl localhost:8080/sample/greeting
Hello World!

$ curl localhost:8080/sample/greeting-by-lookup
Hello World!

$ curl localhost:8080/sample/int-value
15

全部変更されましたね。

環境変数で設定を上書きする場合。

$ export SAMPLE_GREETING_MESSAGE='Hello World!'
$ export SAMPLE_INT_VALUE=15

$ java -jar target/quarkus-configuration-0.0.1-SNAPSHOT-runner.jar

上書きした値は、システムプロパティの時と同じなので省略します。

続いて、ネイティブイメージを作成して確認してみましょう。

$ mvn package -Dnative

起動しようとすると…怒られます。

$ ./target/quarkus-configuration-0.0.1-SNAPSHOT-runner 
java.util.ServiceConfigurationError: org.eclipse.microprofile.config.spi.ConfigSourceProvider: Provider io.quarkus.runtime.configuration.TemporaryConfigSourceProvider not found
    at java.util.ServiceLoader.fail(ServiceLoader.java:239)
    at java.util.ServiceLoader.access$300(ServiceLoader.java:185)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:372)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
    at java.lang.Iterable.forEach(Iterable.java:74)
    at io.smallrye.config.SmallRyeConfigBuilder.discoverSources(SmallRyeConfigBuilder.java:80)
    at io.smallrye.config.SmallRyeConfigBuilder.build(SmallRyeConfigBuilder.java:190)
    at io.quarkus.runtime.generated.RunTimeConfig.getRunTimeConfiguration(Unknown Source)
    at io.quarkus.runner.ApplicationImpl1.doStart(Unknown Source)
    at io.quarkus.runtime.Application.start(Application.java:101)
    at io.quarkus.runtime.Application.run(Application.java:213)
    at io.quarkus.runner.GeneratedMain.main(Unknown Source)
Exception in thread "main" java.lang.RuntimeException: Failed to start quarkus
    at io.quarkus.runner.ApplicationImpl1.doStart(Unknown Source)
    at io.quarkus.runtime.Application.start(Application.java:101)
    at io.quarkus.runtime.Application.run(Application.java:213)
    at io.quarkus.runner.GeneratedMain.main(Unknown Source)
Caused by: java.util.ServiceConfigurationError: org.eclipse.microprofile.config.spi.ConfigSourceProvider: Provider io.quarkus.runtime.configuration.TemporaryConfigSourceProvider not found
    at java.util.ServiceLoader.fail(ServiceLoader.java:239)
    at java.util.ServiceLoader.access$300(ServiceLoader.java:185)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:372)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
    at java.lang.Iterable.forEach(Iterable.java:74)
    at io.smallrye.config.SmallRyeConfigBuilder.discoverSources(SmallRyeConfigBuilder.java:80)
    at io.smallrye.config.SmallRyeConfigBuilder.build(SmallRyeConfigBuilder.java:190)
    at io.quarkus.runtime.generated.RunTimeConfig.getRunTimeConfiguration(Unknown Source)
    ... 4 more

どうやら、QuarkusのService Providerで参照している、Configuration for MicroProfileのConfigSourceProviderの実装クラスが
見つけられないようです。

https://github.com/quarkusio/quarkus/blob/0.14.0/core/runtime/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider

もしかして、リフレクションの情報を登録する必要がある?

というわけで、pom.xmlにGraalVM(Substrate VM)への依存関係を追加して

    <dependency>
      <groupId>com.oracle.substratevm</groupId>
      <artifactId>svm</artifactId>
      <version>1.0.0-rc16</version>
      <scope>provided</scope>
    </dependency>

対象のクラスの情報を登録します。 src/main/java/org/littlewings/quarkus/configuration/QuarkusConfigurationSubstitutions.java

package org.littlewings.quarkus.configuration;

import com.oracle.svm.core.annotate.AutomaticFeature;
import io.quarkus.runtime.configuration.TemporaryConfigSourceProvider;
import org.graalvm.nativeimage.Feature;
import org.graalvm.nativeimage.RuntimeReflection;

public class QuarkusConfigurationSubstitutions {
}

@AutomaticFeature
class RuntimeReflectionRegistrationFeature implements Feature {
    @Override
    public void beforeAnalysis(Feature.BeforeAnalysisAccess access) {
        try {
            RuntimeReflection.register(TemporaryConfigSourceProvider.class);
            RuntimeReflection.register(TemporaryConfigSourceProvider.class.getDeclaredConstructor());
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }
}

再度パッケージングして、起動。

$ ./target/quarkus-configuration-0.0.1-SNAPSHOT-runner

今度は、起動します。確認結果は、JARファイルでの実行の時と同じなので、省略します。

ネイティブイメージでもJARファイルでの実行の時と同様、システムプロパティや

$ ./target/quarkus-configuration-0.0.1-SNAPSHOT-runner -Dsample.greeting.message='Hello World!' -Dsample.int.value=15 -Dcustom.message='Hello!?'

環境変数で値を上書きすることができます。

$ export SAMPLE_GREETING_MESSAGE='Hello World!'
$ export SAMPLE_INT_VALUE=15

$ ./target/quarkus-configuration-0.0.1-SNAPSHOT-runner

環境変数はまあいいとして、システムプロパティはこの場合、ただのコマンドライン引数になっているのでは?と思うのですが、
どうなっているのでしょう。ちょっとわかりませんでした…。

独自の設定ファイルを追加する(ネイティブイメージの時は未確認)

Quarkusでは、デフォルトの設定ファイルをapplication.propertiesとしています。

https://github.com/quarkusio/quarkus/blob/0.14.0/core/runtime/src/main/java/io/quarkus/runtime/configuration/ApplicationPropertiesConfigSource.java#L27

ここで、Configuration for MicroProfileの仕様に沿って、独自の設定項目を追加してみましょう。

Custom configuration sources

こんな設定ファイルを作成。
src/main/resources/my-custom-configuration.properties

custom.message = My Custom Configuration!!

この設定ファイルを読み込む、ConfigSourceProviderの実装を作成します。
src/main/java/org/littlewings/quarkus/configuration/MyCustomConfigSourceProvider.java

package org.littlewings.quarkus.configuration;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;

import io.smallrye.config.PropertiesConfigSource;
import org.eclipse.microprofile.config.spi.ConfigSource;
import org.eclipse.microprofile.config.spi.ConfigSourceProvider;

public class MyCustomConfigSourceProvider implements ConfigSourceProvider {
    @Override
    public Iterable<ConfigSource> getConfigSources(ClassLoader forClassLoader) {
        return Arrays
                .asList("my-custom-configuration.properties")
                .stream()
                .map(filePath -> forClassLoader.getResource(filePath))
                .filter(Objects::nonNull)
                .map(filePath -> {
                    try {
                        return new PropertiesConfigSource(filePath);
                    } catch (IOException e) {
                        throw new UncheckedIOException(e);
                    }
                })
                .collect(Collectors.toList());
    }
}

プロパティファイルからのConfigSourceの作成は、SmallRye Configのものを利用しました。

このクラスを、Service Providerの仕組みでロードできるように設定します。
src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSourceProvider

org.littlewings.quarkus.configuration.MyCustomConfigSourceProvider

先ほど作成した設定クラスに、追加した設定ファイルから取得した項目を追加し

@ApplicationScoped
public class MyConfiguration {
    @ConfigProperty(name = "sample.greeting.message")
    String greetingMessage;

    @ConfigProperty(name = "sample.int.value", defaultValue = "10")
    int intValue;

    @ConfigProperty(name = "custom.message")
    String customMessage;

    public String getGreetingMessage() {
        return greetingMessage;
    }

    public int getIntValue() {
        return intValue;
    }

    public String getCustomMessage() {
        return customMessage;
    }
}

JAX-RSのエンドポイントも追加します。

    @GET
    @Path("custom-config-message")
    @Produces(MediaType.TEXT_PLAIN)
    public String customConfigMessage() {
        return myConfiguration.getCustomMessage();
    }

これで、パッケージングして起動。

$ mvn package
$ java -jar target/quarkus-configuration-0.0.1-SNAPSHOT-runner.jar

確認。

$ curl localhost:8080/sample/custom-config-message
My Custom Configuration!!

追加した設定項目を認識していることを、確認できました。

追加した設定ファイルに関する項目についても、システムプロパティや環境変数で上書きすることができます。

$ java -Dcustom.message=FooBar -jar target/quarkus-configuration-0.0.1-SNAPSHOT-runner.jar

ネイティブイメージでも確認してみましょう。

$ mvn package -Dnative

すると、起動する時に設定のバリデーションに失敗したと怒られます。

$ ./target/quarkus-configuration-0.0.1-SNAPSHOT-runner 
javax.enterprise.inject.spi.DeploymentException: No config value of type [class java.lang.String] exists for: custom.message
    at io.quarkus.arc.runtime.ConfigDeploymentTemplate.validateConfigProperties(ConfigDeploymentTemplate.java:48)
    at io.quarkus.deployment.steps.ConfigBuildStep$validateConfigProperties7.deploy(Unknown Source)
    at io.quarkus.runner.ApplicationImpl1.doStart(Unknown Source)
    at io.quarkus.runtime.Application.start(Application.java:101)
    at io.quarkus.runtime.Application.run(Application.java:213)
    at io.quarkus.runner.GeneratedMain.main(Unknown Source)
Exception in thread "main" java.lang.RuntimeException: Failed to start quarkus
    at io.quarkus.runner.ApplicationImpl1.doStart(Unknown Source)
    at io.quarkus.runtime.Application.start(Application.java:101)
    at io.quarkus.runtime.Application.run(Application.java:213)
    at io.quarkus.runner.GeneratedMain.main(Unknown Source)
Caused by: javax.enterprise.inject.spi.DeploymentException: No config value of type [class java.lang.String] exists for: custom.message
    at io.quarkus.arc.runtime.ConfigDeploymentTemplate.validateConfigProperties(ConfigDeploymentTemplate.java:48)
    at io.quarkus.deployment.steps.ConfigBuildStep$validateConfigProperties7.deploy(Unknown Source)
    ... 4 more

ちなみに、システムプロパティなどで明示的に与えると起動できるようになります。

$ ./target/quarkus-configuration-0.0.1-SNAPSHOT-runner -Dcustom.message=test
2019-05-11 01:06:33,495 INFO  [io.quarkus] (main) Quarkus 0.14.0 started in 0.012s. Listening on: http://[::]:8080
2019-05-11 01:06:33,496 INFO  [io.quarkus] (main) Installed features: [cdi, resteasy, resteasy-jsonb]

どうやら、追加した設定ファイルがわかっていないようです。

ちなみに、だいぶ意図的だったのですが、ConfigSourceProviderで設定ファイルが必ずある前提のコードにしてあると、
ネイティブイメージにした時にはファイルが見つけられずにコケることになります…。

public class MyCustomConfigSourceProvider implements ConfigSourceProvider {
    @Override
    public Iterable<ConfigSource> getConfigSources(ClassLoader forClassLoader) {
        return Arrays
                .asList("my-custom-configuration.properties")
                .stream()
                .map(filePath -> forClassLoader.getResource(filePath))
                .filter(Objects::nonNull)
                .map(filePath -> {
                    try {
                        return new PropertiesConfigSource(filePath);
                    } catch (IOException e) {
                        throw new UncheckedIOException(e);
                    }
                })
                .collect(Collectors.toList());
    }
}

なので、今回のConfigSourceProviderは、「設定ファイルがあったら読み込む」という動作にしています。

ちょっと確認のために、JAX-RSリソースクラスのエンドポイントに、こんなメソッドを足してみます。

    @GET
    @Path("dump-properties")
    @Produces(MediaType.TEXT_PLAIN)
    public String dumpProperties() {
        config.getConfigSources().forEach(cs -> {
            System.out.println("====== " + cs.getName());
            cs.getProperties().forEach((k, v) -> System.out.println("  " + k + " = " + v));
        });

        return "OK!!";
    }

現在認識しているConfigSourceを、全部出力してみようと。

この状態で、ひとまずJARファイルで起動してアクセスしてみます。

$ curl localhost:8080/sample/dump-properties

すると、コンソールにはこんな感じで表示されます。

====== SysPropConfigSource
  ...
====== EnvConfigSource
  ...
====== PropertiesConfigSource[source=application.properties]
====== PropertiesConfigSource[source=application.properties]
====== PropertiesConfigSource[source=application.properties]
  sample.greeting.message = Hello Quarkus!!
====== PropertiesConfigSource[source=application.properties]
  sample.greeting.message = Hello Quarkus!!
====== PropertiesConfigSource[source=jar:file:/path/to/quarkus-configuration/target/quarkus-configuration-0.0.1-SNAPSHOT-runner.jar!/my-custom-configuration.properties]
  custom.message = My Custom Configuration!!
====== null:null:ServletConfigSource
====== null:javax.ws.rs.core.Application:FilterConfigSource
====== null:ServletContextConfigSource
  resteasy.injector.factory = io.quarkus.resteasy.runtime.QuarkusInjectorFactory
  resteasy.providers = org.jboss.resteasy.plugins.providers.sse.SseEventOutputProvider,org.jboss.resteasy.plugins.providers.DefaultTextPlain,org.jboss.resteasy.plugins.providers.jsonp.JsonObjectProvider,org.jboss.resteasy.plugins.providers.ReactiveStreamProvider,org.jboss.resteasy.plugins.interceptors.CacheControlFeature,org.jboss.resteasy.plugins.interceptors.ServerContentEncodingAnnotationFeature,org.jboss.resteasy.plugins.providers.CompletionStageProvider,org.jboss.resteasy.plugins.interceptors.ClientContentEncodingAnnotationFeature,org.jboss.resteasy.plugins.providers.DefaultNumberWriter,org.jboss.resteasy.plugins.providers.jsonb.JsonBindingProvider,org.jboss.resteasy.plugins.providers.FileProvider,org.jboss.resteasy.plugins.interceptors.MessageSanitizerContainerResponseFilter,org.jboss.resteasy.plugins.providers.MultiValuedParamConverterProvider,org.jboss.resteasy.plugins.providers.jsonp.JsonArrayProvider,org.jboss.resteasy.plugins.providers.DefaultBooleanWriter,org.jboss.resteasy.plugins.providers.ByteArrayProvider,org.jboss.resteasy.plugins.providers.StringTextStar,org.jboss.resteasy.plugins.providers.StreamingOutputProvider,org.jboss.resteasy.plugins.providers.jsonp.JsonStructureProvider,io.quarkus.resteasy.runtime.RolesFilterRegistrar,org.jboss.resteasy.plugins.providers.ReaderProvider,org.jboss.resteasy.plugins.providers.sse.SseEventSinkInterceptor,org.jboss.resteasy.plugins.providers.DataSourceProvider,org.jboss.resteasy.plugins.providers.FileRangeWriter,org.jboss.resteasy.plugins.providers.InputStreamProvider,org.jboss.resteasy.plugins.providers.jsonp.JsonValueProvider
  resteasy.scanned.resources = org.littlewings.quarkus.configuration.SampleResource
  resteasy.use.builtin.providers = false
  resteasy.servlet.mapping.prefix = /
====== PropertiesConfigSource[source=Default configuration values]
  quarkus.log.filter."org.xnio.nio".if-starts-with = XNIO NIO Implementation Version
  quarkus.log.console.darken = 0
  sample.greeting.message = Hello Quarkus!!
  quarkus.log.filter."org.jboss.resteasy.resteasy_jaxrs.i18n".if-starts-with = RESTEASY002225
  quarkus.log.filter."org.jboss.threads".if-starts-with = JBoss Threads version
  quarkus.log.filter."org.xnio".if-starts-with = XNIO version
====== default values

application.propertiesの内容などが、確認できますね。ところで、application.propertiesと同じ内容が入った以下のようなものもあります。

====== PropertiesConfigSource[source=Default configuration values]

ここで、ネイティブイメージで確認すると、ガラッと結果が変わります。

====== SysPropConfigSource
  ...
====== EnvConfigSource
  ...
====== PropertiesConfigSource[source=application.properties]
====== PropertiesConfigSource[source=application.properties]
====== PropertiesConfigSource[source=application.properties]
====== PropertiesConfigSource[source=application.properties]
====== PropertiesConfigSource[source=Default configuration values]
  quarkus.log.filter."org.xnio.nio".if-starts-with = XNIO NIO Implementation Version
  quarkus.log.console.darken = 0
  sample.greeting.message = Hello Quarkus!!
  quarkus.log.filter."org.jboss.resteasy.resteasy_jaxrs.i18n".if-starts-with = RESTEASY002225
  quarkus.log.filter."org.jboss.threads".if-starts-with = JBoss Threads version
  quarkus.log.filter."org.xnio".if-starts-with = XNIO version
====== default values

こちらの方しか認識していませんね。

====== PropertiesConfigSource[source=Default configuration values]

なので、ネイティブイメージの時には実際には異なるファイルから読み込んでいるようなように見えますね。

その元ネタは、ビルド時に生成されるこちらのファイルのようです。 target/wiring-classes/META-INF/quarkus-default-config.properties

#This is the generated set of default configuration values
#Sat May 11 01:08:30 JST 2019
quarkus.log.filter."org.jboss.resteasy.resteasy_jaxrs.i18n".if-starts-with=RESTEASY002225
quarkus.log.console.darken=0
sample.greeting.message=Hello Quarkus\!\!
quarkus.log.filter."org.xnio".if-starts-with=XNIO version
quarkus.log.filter."org.jboss.threads".if-starts-with=JBoss Threads version
quarkus.log.filter."org.xnio.nio".if-starts-with=XNIO NIO Implementation Version

ソースコードとしては、このあたりに。

https://github.com/quarkusio/quarkus/blob/0.14.0/core/runtime/src/main/java/io/quarkus/runtime/configuration/DefaultConfigSource.java#L20

で、この生成されたquarkus-default-config.properties、Build Time Extensionで細工しているような感じに見えます。

https://github.com/quarkusio/quarkus/blob/0.14.0/core/deployment/src/main/java/io/quarkus/deployment/steps/ConfigurationSetup.java#L393-L402

CDI REFERENCE / Build Time Extension Points

https://quarkus.io/guides/extension-authors-guide.html

なんかちょっと遠そうなので、今回はこのあたりで。

どこかでBuild Time Extensionを覚えるなりしてから、また戻ってきましょう。

ネイティブイメージにする時には、いろいろあるんですねぇ…。

まとめ

QuarkusでのConfiguration for MicroProfileを試してみました。

JARファイルでの実行でも、ネイティブイメージの実行でも使えますが、追加の設定ファイルを書いたりすると、
ネイティブイメージにした時に困ったことになるような…。

とりあえず、今はapplication.propertiesだけを使っておくのが無難ですかねぇ。