quarkus: `QuarkusUnitTest` throws "No config found for class" when writing extension using Kotlin

Describe the bug

When I write a Quarkus extension using Kotlin, I could’t get QuarkusUnitTest mechanism working properly if I have a config class defined in runtime module and used in a build step in deployment module.

If I changed to Java, works fine.

Current workaround is manually creating a file META-INF/quarkus-config-roots.list and list the config class there, but as described in the following link this file is not supposed to be edited manually: https://quarkus.io/guides/extension-metadata#quarkus-config-roots

Apart from this issue, defining config class using Kotlin isn’t nice experience, e.g. can’t use data class and Kotlin native types, has to put @JvmField on each field and make sure the field is declared using var instead of val, etc.

Expected behavior

Should not throw error

Actual behavior

Can’t find config class, throw exception:

Caused by: io.quarkus.builder.BuildException: Build failure: Build failed due to errors [error]: Build step demo.DemoProcessor#helloServlet threw an exception: java.lang.IllegalStateException: No config found for class demo.HelloConfig at io.quarkus.deployment.configuration.BuildTimeConfigurationReader$ReadResult.requireObjectForClass(BuildTimeConfigurationReader.java:1274) at io.quarkus.deployment.ExtensionLoader.lambda$loadStepsFromClass$55(ExtensionLoader.java:591) at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:860) at io.quarkus.builder.BuildContext.run(BuildContext.java:282) at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18) at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538) at java.base/java.lang.Thread.run(Thread.java:833) at org.jboss.threads.JBossThread.run(JBossThread.java:501)

at app//io.quarkus.builder.Execution.run(Execution.java:123) at app//io.quarkus.builder.BuildExecutionBuilder.execute(BuildExecutionBuilder.java:79) at app//io.quarkus.deployment.QuarkusAugmentor.run(QuarkusAugmentor.java:160) at app//io.quarkus.runner.bootstrap.AugmentActionImpl.runAugment(AugmentActionImpl.java:332) … 59 more Caused by: java.lang.IllegalStateException: No config found for class demo.HelloConfig at io.quarkus.deployment.configuration.BuildTimeConfigurationReader$ReadResult.requireObjectForClass(BuildTimeConfigurationReader.java:1274) at io.quarkus.deployment.ExtensionLoader.lambda$loadStepsFromClass$55(ExtensionLoader.java:591) at io.quarkus.deployment.ExtensionLoader$3.execute(ExtensionLoader.java:860) at io.quarkus.builder.BuildContext.run(BuildContext.java:282) at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18) at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538) at java.base/java.lang.Thread.run(Thread.java:833) at org.jboss.threads.JBossThread.run(JBossThread.java:501)

How to Reproduce?

Example project demo this issue:

https://github.com/jeffawx/quarkus-ext-test

If this file is removed: https://github.com/jeffawx/quarkus-ext-test/blob/main/deployment/src/main/resources/META-INF/quarkus-config-roots.list

build will fail: ./gradlew clean build

Output of uname -a or ver

No response

Output of java -version

openjdk 17.0.7 2023-04-18 OpenJDK Runtime Environment Temurin-17.0.7+7 (build 17.0.7+7) OpenJDK 64-Bit Server VM Temurin-17.0.7+7 (build 17.0.7+7, mixed mode)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

3.2.2.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Gradle 8.0

Additional information

No response

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Comments: 15 (8 by maintainers)

Most upvoted comments

It works when running the test-app because you are referencing the resulting jars of the extension, which contains the quarkus-config-root.list.

The issue here is kapt is generating the output in a different folder from build/classes or build/resources as you would expect. For a Gradle dependency project these are the expected directories to find each project module output. There should be a way to change the output path.

Another easier alternative is copy the generated file to the main build output. Adding this to the runtime module, the test passes as expected:

tasks.register<Copy>("copyConfigRoots") {
    from(layout.buildDirectory.file("tmp/kapt3/classes/main/META-INF/quarkus-config-roots.list"))
    into(layout.buildDirectory.dir("resources/main/META-INF/"))
}

tasks.named("build") {
    finalizedBy("copyConfigRoots")
}

Can you update your sample with ConfigMapping?

Yep pushed the changes here: https://github.com/jeffawx/quarkus-ext-test

if you run ./gradlew test it should pass test, but if you remove META-INF/quarkus-config-roots.list will fail

Also confirmed this test extension works properly in real application.