Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@ConfigMapping fails with default function implementations in interfaces in Kotlin projects #20496

Closed
Shpota opened this issue Oct 1, 2021 · 8 comments · Fixed by #20870
Closed
Assignees
Labels
Milestone

Comments

@Shpota
Copy link

Shpota commented Oct 1, 2021

If an interface annotated with @ConfigMapping has a default function implementation the application fails on startup.

Actual behavior

2021-10-01 12:52:36,571 ERROR [io.qua.run.Application] (Quarkus Main Thread) Failed to start application (with profile dev): io.smallrye.config.ConfigValidationException: Configuration validation failed:
        java.util.NoSuchElementException: SRCFG00014: The config property server.server-url is required but it could not be found in any config source
        at io.smallrye.config.ConfigMappingProvider.mapConfiguration(ConfigMappingProvider.java:838)
        at io.smallrye.config.ConfigMappingProvider.mapConfiguration(ConfigMappingProvider.java:794)
        at io.smallrye.config.ConfigMappings.mapConfiguration(ConfigMappings.java:54)
        at io.smallrye.config.ConfigMappings.registerConfigMappings(ConfigMappings.java:36)
        at io.quarkus.arc.runtime.ConfigRecorder.registerConfigMappings(ConfigRecorder.java:81)
        at io.quarkus.deployment.steps.ConfigBuildStep$registerConfigClasses-2116437784.deploy_0(ConfigBuildStep$registerConfigClasses-2116437784.zig:132)
        at io.quarkus.deployment.steps.ConfigBuildStep$registerConfigClasses-2116437784.deploy(ConfigBuildStep$registerConfigClasses-2116437784.zig:40)
        at io.quarkus.runner.ApplicationImpl.doStart(ApplicationImpl.zig:612)
        at io.quarkus.runtime.Application.start(Application.java:101)
        at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:101)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:66)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:42)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:119)
        at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:29)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at io.quarkus.runner.bootstrap.StartupActionImpl$1.run(StartupActionImpl.java:98)
        at java.base/java.lang.Thread.run(Thread.java:832)

How to Reproduce?

  1. Generate a Quarkus project with Kotlin, Gradle, and yaml.
  2. Replace application.properties with application.yml with the following content:
server:
  host: "localhost"
  1. Create a ServerConfig interface with the following class:
@ConfigMapping(prefix = "server")
interface ServerConfig {
    fun host(): String

    fun serverUrl(): String = "https://${host()}"
}
  1. Run: ./gradlew quarkusDev and observer the error.

Quarkus version or git rev

2.2.3.Final

@Shpota Shpota added the kind/bug Something isn't working label Oct 1, 2021
@quarkus-bot
Copy link

quarkus-bot bot commented Oct 1, 2021

/cc @evanchooly

@Shpota Shpota changed the title @ConfigMapping doesn't with default function implementations in interfaces in Kotlin projects @ConfigMapping fails with default function implementations in interfaces in Kotlin projects Oct 1, 2021
@radcortez
Copy link
Member

@evanchooly do you know how can we tell if a method has been implemented on Kotlin? In this case, when we look into the method, it shows as abstract so we think that is not implemented and we add it as a configuration item.

@Shpota
Copy link
Author

Shpota commented Oct 1, 2021

@radcortez the bytecode of the Kotlin interface that I posted would look somewhat like this in Java:

public interface ServerConfig {
    String host();
    
    String serverUrl();
    
    public static final class DefaultImpls {
        public static String serverUrl(ServerConfig config) {
            return "https://" + config.host();
        }
    }
}

@radcortez
Copy link
Member

Thanks. Let me have a look.

@evanchooly
Copy link
Member

Have what you need @radcortez ?

@radcortez
Copy link
Member

Have what you need @radcortez ?

Maybe. I'll need to adjust the code to look for this and ignore the method. Is this the only way that Kotlin provides the implementation? I was looking into https://youtrack.jetbrains.com/issue/KT-4779

@evanchooly
Copy link
Member

what bytecode are you seeing that's problematic, exactly?

@radcortez
Copy link
Member

what bytecode are you seeing that's problematic, exactly?

No problem at all so far. It is clear. I'm only concerned about the different ways that it behaves depending on the compiler flags, but I'm guessing that we can just ignore that and provide the bridge to the generated defaults if one exists.

@radcortez radcortez self-assigned this Oct 13, 2021
@quarkus-bot quarkus-bot bot added this to the 2.5 - main milestone Oct 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants