quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.82k stars 2.69k forks source link

2.10.3.Final -> ServiceConfigurationError: SmallRyeConfigFactory: QuarkusConfigFactory not a subtype #26953

Closed lthasle closed 2 years ago

lthasle commented 2 years ago

Describe the bug

When moving from 2.10.2.Final to 2.10.3.Final, I see that some of our tests fails with this error, see test output below.

https://quarkusio.zulipchat.com/#narrow/stream/187030-users/topic/2.2E10.2E3.2EFinal.20-.3E.20ServiceConfigurationError.3A.20SmallRyeConfigFac

Expected behavior

The test should run ok as in previous version 2.10.2.Final

Actual behavior

The test fails: [ERROR] app.ArkivControllerMockTest.tst Time elapsed: 0.772 s <<< ERROR! java.lang.RuntimeException: java.lang.reflect.InvocationTargetException Caused by: java.lang.reflect.InvocationTargetException Caused by: java.util.ServiceConfigurationError: io.smallrye.config.SmallRyeConfigFactory: io.quarkus.runtime.configuration.QuarkusConfigFactory not a subtype

How to Reproduce?

run the provided test and observer the error The test run will succeed if you revert back to: 2.10.2.Final The test will also succeed if the CircuitBreaker are removed from the interface bsf-online2.zip

Output of uname -a or ver

Linux hty80028.sb1a.sparebank1.no 4.18.0-372.16.1.el8_6.x86_64 #1 SMP Tue Jun 28 03:02:21 EDT 2022 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

openjdk version "17.0.3" 2022-04-19 OpenJDK Runtime Environment Temurin-17.0.3+7 (build 17.0.3+7) OpenJDK 64-Bit Server VM Temurin-17.0.3+7 (build 17.0.3+7, mixed mode, sharing)

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.10.3.Final

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

No response

Additional information

No response

quarkus-bot[bot] commented 2 years ago

/cc @Ladicek, @jmartisk, @phillip-kruger, @radcortez

quarkus-bot[bot] commented 2 years ago

You added a link to a Zulip discussion, please make sure the description of the issue is comprehensive and doesn't require accessing Zulip.

This message is automatically generated by a bot.

Ladicek commented 2 years ago

The shortened stack trace in this issue doesn't show anything, but the full stacktrace in the Zulip discussion shows that the problem occurs at

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at io.quarkus.test.junit.QuarkusTestExtension.popMockContext(QuarkusTestExtension.java:675)
    at io.quarkus.test.junit.QuarkusTestExtension.afterEach(QuarkusTestExtension.java:510)

and the popMockContext method calls

Caused by: java.util.ServiceConfigurationError: io.smallrye.config.SmallRyeConfigFactory: io.quarkus.runtime.configuration.QuarkusConfigFactory not a subtype
    at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:593)
    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1244)
    at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1273)
    at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1309)
    at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1393)
    at io.smallrye.config.SmallRyeConfigProviderResolver.getFactoryFor(SmallRyeConfigProviderResolver.java:100)
    at io.smallrye.config.SmallRyeConfigProviderResolver.getConfig(SmallRyeConfigProviderResolver.java:76)
    at io.smallrye.config.SmallRyeConfigProviderResolver.getConfig(SmallRyeConfigProviderResolver.java:64)
    at org.eclipse.microprofile.config.ConfigProvider.getConfig(ConfigProvider.java:85)
    at io.smallrye.faulttolerance.config.CircuitBreakerConfigImpl.delayUnit(CircuitBreakerConfigImpl.java:180)
    at io.smallrye.faulttolerance.FaultToleranceInterceptor.prepareSyncStrategy(FaultToleranceInterceptor.java:365)
    at io.smallrye.faulttolerance.FaultToleranceInterceptor.lambda$syncFlow$2(FaultToleranceInterceptor.java:250)
    at io.smallrye.faulttolerance.internal.StrategyCache.lambda$getStrategy$0(StrategyCache.java:20)
    at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
    at io.smallrye.faulttolerance.internal.StrategyCache.getStrategy(StrategyCache.java:20)
    at io.smallrye.faulttolerance.FaultToleranceInterceptor.syncFlow(FaultToleranceInterceptor.java:250)
    at io.smallrye.faulttolerance.FaultToleranceInterceptor.intercept(FaultToleranceInterceptor.java:182)
    at io.smallrye.faulttolerance.FaultToleranceInterceptor_Bean.intercept(Unknown Source)
    at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
    at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:40)
    at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
    at sb1.fip.app.bsf.online.client.SkadeTilbudDocClient$$CDIWrapper_Subclass.clearMock(Unknown Source)
    at sb1.fip.app.bsf.online.client.SkadeTilbudDocClient$$CDIWrapper_ClientProxy.clearMock(Unknown Source)
    at io.quarkus.test.junit.MockSupport.popContext(MockSupport.java:28)

That is, during @AfterEach, we call clearMock, which gets intercepted (because the RestClient interface has a class-level fault tolerance annotation), and that is wrong.

The fix is simple: the 2 methods related to mocking on RestClientReactiveCDIWrapperBase are missing the @NoClassInterceptors annotation. I'll submit a PR, though I'll first take a look whether there's a simpler / more direct test than the reproducer attached.

geoand commented 2 years ago

Thanks for taking care of this @Ladicek