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

quarkus.test.integration-test-profile ignored in IT startup error message if startup fails because of ConfigValidationException #36376

Closed
yrodiere opened this issue Oct 10, 2023 · 7 comments · Fixed by #37543
Labels
area/config area/testing good first issue Good for newcomers kind/bug Something isn't working
Milestone

Comments

@yrodiere
Copy link
Member

yrodiere commented Oct 10, 2023

Describe the bug

If I set this:

quarkus.test.integration-test-profile=integrationtest

and for some reason my application fails to start in integration tests, during config resolution, the error message looks like this:

ERROR: Failed to start application (with profile [prod])
java.lang.RuntimeException: Failed to start quarkus
        at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)

... even though the profile prod is NOT active, as evidenced by the command being executed:

Executing "... -Dquarkus.profile=integrationtest ..."

Expected behavior

ERROR: Failed to start application (with profile [integrationtest])

Actual behavior

ERROR: Failed to start application (with profile [prod])
java.lang.RuntimeException: Failed to start quarkus
        at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
        at io.quarkus.runtime.Application.start(Application.java:101)
        at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:111)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:71)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:44)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:124)
        at io.quarkus.runner.GeneratedMain.main(Unknown Source)
Caused by: io.smallrye.config.ConfigValidationException: Configuration validation failed:
        java.util.NoSuchElementException: SRCFG00011: Could not expand value maven.test.data.path in property uris.quarkusio.local
        at io.smallrye.config.ConfigMappingProvider.mapConfigurationInternal(ConfigMappingProvider.java:1001)
        at io.smallrye.config.ConfigMappingProvider.lambda$mapConfiguration$3(ConfigMappingProvider.java:961)
        at io.smallrye.config.SecretKeys.doUnlocked(SecretKeys.java:28)
        at io.smallrye.config.ConfigMappingProvider.mapConfiguration(ConfigMappingProvider.java:961)
        at io.smallrye.config.ConfigMappings.mapConfiguration(ConfigMappings.java:91)
        at io.smallrye.config.SmallRyeConfigBuilder.build(SmallRyeConfigBuilder.java:647)
        at io.quarkus.runtime.generated.Config.readConfig(Unknown Source)
        at io.quarkus.runtime.generated.Config.createRunTimeConfig(Unknown Source)
        at io.quarkus.deployment.steps.RuntimeConfigSetup.deploy(Unknown Source)
        ... 7 more

How to Reproduce?

Just adding something like this to an application should have done the trick:

quarkus.test.integration-test-profile=integrationtest
%integrationtest.hello.message=${some-unresolved-property}

Assuming the application also includes this:

@Path("/hello")
public class GreetingResource {

    @ConfigMapping(prefix = "hello")
    public interface MyConfig {
        String message();
    }

    @Inject
    MyConfig config;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return config.message();
    }
}

But here's a full reproducer:

git clone -b i36376 https://github.com/yrodiere/quarkus-playground.git
cd quarkus-playground
./mvnw clean verify -Dnative

When build ends (it'll take a while), see how the logs are inconsistent:

[...]
Executing "/home/yrodiere/workspaces/testcases/quarkus-playground/target/code-with-quarkus-1.0.0-SNAPSHOT-runner -Dquarkus.http.port=8081 -Dquarkus.http.ssl-port=8444 -Dtest.url=http://localhost:8081 -Dquarkus.log.file.path=/home/yrodiere/workspaces/testcases/quarkus-playground/target/quarkus.log -Dquarkus.log.file.enable=true -Dquarkus.log.category."io.quarkus".level=INFO -Dquarkus.profile=integrationtest -Dquarkus.datasource.password=quarkus -Dquarkus.datasource.db-kind=postgresql -Dquarkus.datasource.jdbc.url=jdbc:postgresql://localhost:43893/quarkus?loggerLevel=OFF -Dquarkus.datasource.username=quarkus -Dquarkus.hibernate-orm.database.generation=drop-and-create"
[...]
ERROR: Failed to start application (with profile [prod])
java.lang.RuntimeException: Failed to start quarkus
[...]

The first line shows -Dquarkus.profile=integrationtest but the error shows with profile [prod].

Output of uname -a or ver

No response

Output of java -version

No response

GraalVM version (if different from Java)

No response

Quarkus version or git rev

No response

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

No response

Additional information

I think this can only be reproduced if the startup failure happens during config resolution. That would make sense, as in that case I suspect ConfigUtils.getProfiles() just returns garbage that doesn't take config into account, so this would not behave properly:

// If it is not a ConfigurationException it should be safe to call ConfigProvider.getConfig here
applicationLogger.errorv(e, "Failed to start application (with profile {0})",
ConfigUtils.getProfiles());
ensureConsoleLogsDrained();

@yrodiere yrodiere added the kind/bug Something isn't working label Oct 10, 2023
@yrodiere yrodiere changed the title quarkus.test.integration-test-profile ignored in IT startup error message quarkus.test.integration-test-profile ignored in IT startup error message if startup fails because of ConfigValidationException Oct 10, 2023
@yrodiere
Copy link
Member Author

I see we have a special case for io.quarkus.runtime.configuration.ConfigurationException:

} else if (rootCause instanceof ConfigurationException) {
System.err.println(rootCause.getMessage());
} else if (rootCause instanceof PreventFurtherStepsException
&& !StringUtil.isNullOrEmpty(rootCause.getMessage())) {
System.err.println(rootCause.getMessage());
} else {
// If it is not a ConfigurationException it should be safe to call ConfigProvider.getConfig here
applicationLogger.errorv(e, "Failed to start application (with profile {0})",
ConfigUtils.getProfiles());
ensureConsoleLogsDrained();
}

Maybe we need something similar for io.smallrye.config.ConfigValidationException?

@geoand
Copy link
Contributor

geoand commented Oct 10, 2023

Maybe we need something similar for io.smallrye.config.ConfigValidationException?

Seems reasonable

@yrodiere yrodiere added the good first issue Good for newcomers label Oct 10, 2023
@dvsingh9
Copy link

@geoand io.smallrye.config.ConfigValidationException is external exception not from quarkus-core, how to catch it within ApplicationLifecycleManager ?

@yrodiere
Copy link
Member Author

@dvsingh9 Right. I think you'd have to find some place in the stack trace where you could catch it and wrap it with a io.quarkus.runtime.configuration.ConfigurationException instead (making sure to copy the exception message and to preserve the cause, of course).

RuntimeConfigSetup#deploy looks like a good place to do this, but it seems like it's generated code, so it might be a bit complex if you're not used to that :)

@MaciejDromin
Copy link
Contributor

Hello @yrodiere I started investigating this issue but couldn't quite reproduce it. Also when I build my custom quarkus-core project changing ApplicationLifecycleManager.java and included it as dependency it seems that those changes did not have any effect. Do you have maybe some hints for the newcomer? :)

@yrodiere
Copy link
Member Author

yrodiere commented Dec 5, 2023

Hey @MaciejDromin , thanks for having a look.

I updated the issue description with a reproducer.

Note however that #37401 might have fixed the problem already. I'm not entirely sure, one would have to run the reproducer against a build of Quarkus on the main branch (right now the reproducer uses Quarkus 3.6.0).

@MaciejDromin
Copy link
Contributor

@yrodiere Thanks for your reply! I was able to test this with the latest code and the issue still occurs. I created PR fixing this, hope it is good enough :)

MaciejDromin added a commit to MaciejDromin/quarkus that referenced this issue Dec 6, 2023
yrodiere added a commit that referenced this issue Dec 21, 2023
Fix smallrye ConfigValidationException not being handled properly at Quarkus startup
@quarkus-bot quarkus-bot bot added this to the 3.7 - main milestone Dec 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/config area/testing good first issue Good for newcomers kind/bug Something isn't working
Projects
None yet
4 participants