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

Injecting ConfigMapping in resteasy containerrequestfilter causes NoSuchElementException #18333

Closed
Postremus opened this issue Jul 2, 2021 · 12 comments · Fixed by #18497 or #20103
Closed
Assignees
Labels
area/config env/windows Impacts Windows machines kind/bug Something isn't working
Milestone

Comments

@Postremus
Copy link
Member

Describe the bug

This one is quite similar to #17466, except this issue is about containerrequestfilter, while the other was about requestscoped observer.

@Provider
public class Filter implements ContainerRequestFilter {
    @Inject
    SomeConfigMapping config;

    @Override public void filter(ContainerRequestContext requestContext) throws IOException {
        System.out.println(config.value());
    }
}
@ConfigMapping(prefix = "some")
public interface SomeConfigMapping {
    @WithName("value")
    String value();
}

Expected behavior

App should start without problems.

Actual behavior

2021-07-02 08:32:01,404 INFO  [io.qua.dep.dev.IsolatedDevModeMain] (main) Attempting to start live reload endpoint to recover from previous Quarkus startup failure
2021-07-02 08:32:01,404 ERROR [io.qua.run.boo.StartupActionImpl] (Quarkus Main Thread) Error running Quarkus: java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at io.quarkus.runner.bootstrap.StartupActionImpl$1.run(StartupActionImpl.java:98)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.ExceptionInInitializerError
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at java.base/java.lang.Class.newInstance(Class.java:584)
        at io.quarkus.runtime.Quarkus.run(Quarkus.java:65)
        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)
        ... 6 more
Caused by: java.lang.RuntimeException: Failed to start quarkus
        at io.quarkus.runner.ApplicationImpl.<clinit>(ApplicationImpl.zig:291)
        ... 15 more
Caused by: java.lang.RuntimeException: Error injecting org.acme.SomeConfigMapping org.acme.Filter.config
        at org.acme.Filter_Bean.create(Filter_Bean.zig:199)
        at org.acme.Filter_Bean.create(Filter_Bean.zig:222)
        at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:96)
        at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:29)
        at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:26)
        at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26)
        at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69)
        at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:26)
        at org.acme.Filter_Bean.get(Filter_Bean.zig:254)
        at org.acme.Filter_Bean.get(Filter_Bean.zig:270)
        at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:430)
        at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:443)
        at io.quarkus.arc.impl.ArcContainerImpl$1.get(ArcContainerImpl.java:266)
        at io.quarkus.arc.impl.ArcContainerImpl$1.get(ArcContainerImpl.java:263)
        at io.quarkus.resteasy.common.runtime.QuarkusConstructorInjector.construct(QuarkusConstructorInjector.java:39)
        at org.jboss.resteasy.core.providerfactory.ResteasyProviderFactoryImpl.injectedInstance(ResteasyProviderFactoryImpl.java:1399)
        at org.jboss.resteasy.core.interception.jaxrs.JaxrsInterceptorRegistryImpl$AbstractInterceptorFactory.createInterceptor(JaxrsInterceptorRegistryImpl.java:150)
        at org.jboss.resteasy.core.interception.jaxrs.JaxrsInterceptorRegistryImpl$OnDemandInterceptorFactory.initialize(JaxrsInterceptorRegistryImpl.java:168)
        at org.jboss.resteasy.core.interception.jaxrs.JaxrsInterceptorRegistryImpl$OnDemandInterceptorFactory.checkInitialize(JaxrsInterceptorRegistryImpl.java:183)
        at org.jboss.resteasy.core.interception.jaxrs.JaxrsInterceptorRegistryImpl$OnDemandInterceptorFactory.getInterceptor(JaxrsInterceptorRegistryImpl.java:193)
        at org.jboss.resteasy.core.interception.jaxrs.JaxrsInterceptorRegistryImpl$AbstractInterceptorFactory.postMatch(JaxrsInterceptorRegistryImpl.java:131)
        at org.jboss.resteasy.core.interception.jaxrs.JaxrsInterceptorRegistryImpl.postMatch(JaxrsInterceptorRegistryImpl.java:288)
        at org.jboss.resteasy.core.interception.jaxrs.ContainerRequestFilterRegistryImpl.postMatch(ContainerRequestFilterRegistryImpl.java:30)
        at org.jboss.resteasy.core.interception.jaxrs.ContainerRequestFilterRegistryImpl.postMatch(ContainerRequestFilterRegistryImpl.java:12)
        at org.jboss.resteasy.core.ResourceMethodInvoker.<init>(ResourceMethodInvoker.java:142)
        at org.jboss.resteasy.core.ResourceMethodRegistry.processMethod(ResourceMethodRegistry.java:381)
        at org.jboss.resteasy.core.ResourceMethodRegistry.register(ResourceMethodRegistry.java:308)
        at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:259)
        at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:227)
        at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:208)
        at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:192)
        at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:175)
        at org.jboss.resteasy.core.ResourceMethodRegistry.addPerRequestResource(ResourceMethodRegistry.java:87)
        at org.jboss.resteasy.core.ResteasyDeploymentImpl.registerResources(ResteasyDeploymentImpl.java:518)
        at org.jboss.resteasy.core.ResteasyDeploymentImpl.registration(ResteasyDeploymentImpl.java:475)
        at org.jboss.resteasy.core.ResteasyDeploymentImpl.startInternal(ResteasyDeploymentImpl.java:164)
        at org.jboss.resteasy.core.ResteasyDeploymentImpl.start(ResteasyDeploymentImpl.java:121)
        at io.quarkus.resteasy.runtime.standalone.ResteasyStandaloneRecorder.staticInit(ResteasyStandaloneRecorder.java:37)
        at io.quarkus.deployment.steps.ResteasyStandaloneBuildStep$staticInit-210558872.deploy_0(ResteasyStandaloneBuildStep$staticInit-210558872.zig:903)
        at io.quarkus.deployment.steps.ResteasyStandaloneBuildStep$staticInit-210558872.deploy(ResteasyStandaloneBuildStep$staticInit-210558872.zig:40)
        at io.quarkus.runner.ApplicationImpl.<clinit>(ApplicationImpl.zig:260)
        ... 15 more
Caused by: java.util.NoSuchElementException: SRCFG00027: Could not find a mapping for org.acme.SomeConfigMapping
        at io.smallrye.config.ConfigMappings.getConfigMapping(ConfigMappings.java:73)
        at io.smallrye.config.SmallRyeConfig.getConfigMapping(SmallRyeConfig.java:357)
        at io.quarkus.arc.runtime.ConfigMappingCreator.create(ConfigMappingCreator.java:28)
        at org.acme.SomeConfigMapping_2d5671bb9f49e16a6bde817d1dc2ee2e8da3440b_Synthetic_Bean.create(SomeConfigMapping_2d5671bb9f49e16a6bde817d1dc2ee2e8da3440b_Synthetic_Bean.zig:128)
        at org.acme.SomeConfigMapping_2d5671bb9f49e16a6bde817d1dc2ee2e8da3440b_Synthetic_Bean.get(SomeConfigMapping_2d5671bb9f49e16a6bde817d1dc2ee2e8da3440b_Synthetic_Bean.zig:159)
        at org.acme.SomeConfigMapping_2d5671bb9f49e16a6bde817d1dc2ee2e8da3440b_Synthetic_Bean.get(SomeConfigMapping_2d5671bb9f49e16a6bde817d1dc2ee2e8da3440b_Synthetic_Bean.zig:182)
        at io.quarkus.arc.impl.CurrentInjectionPointProvider.get(CurrentInjectionPointProvider.java:52)
        at org.acme.Filter_Bean.create(Filter_Bean.zig:182)
        ... 55 more

2021-07-02 08:32:01,467 INFO  [org.jbo.threads] (main) JBoss Threads version 3.4.0.Final

To Reproduce

Steps to reproduce the behavior:

  1. Download the reproducer:
    requestscoped-test.zip
  2. mvn quarkus:dev
  3. app does not start
  4. Remove the filter class
  5. mvn quarkus:dev
  6. The app starts

Configuration

some.value=abc

Environment (please complete the following information):

Output of uname -a or ver

MSYS_NT-10.0 NANB7NLNVP2 2.10.0(0.325/5/3) 2018-06-13 23:34 x86_64 Msys

Output of java -version

openjdk 11.0.7 2020-04-14 LTS
OpenJDK Runtime Environment Zulu11.39+15-CA (build 11.0.7+10-LTS)
OpenJDK 64-Bit Server VM Zulu11.39+15-CA (build 11.0.7+10-LTS, mixed mode)

Quarkus version or git rev

2.0.0.Final

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

Apache Maven 3.8.1 (05c21c65bdfed0f71a2f2ada8b84da59348c4c5d)
Maven home: C:\eclipse\tools\apache-maven\bin..
Java version: 11.0.7, vendor: Azul Systems, Inc., runtime: C:\eclipse\tools\java\11
Default locale: de_DE, platform encoding: Cp1252
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

@Postremus Postremus added the kind/bug Something isn't working label Jul 2, 2021
@quarkus-bot quarkus-bot bot added the env/windows Impacts Windows machines label Jul 2, 2021
@Postremus
Copy link
Member Author

/cc @radcortez fyi

@gsmet
Copy link
Member

gsmet commented Jul 2, 2021

/cc @geoand too

@geoand
Copy link
Contributor

geoand commented Jul 2, 2021

@radcortez why would this be happening? What is special about @ConfigMapping that would cause this?
Or is the problem that the mapping is getting instantiated too early?

Is this perhaps similar to #18237 ?

@radcortez
Copy link
Member

Yes, the mappings are only registered for the runtime Config instance, not for static config.

Again, that is on purpose, because not every source may be available on static init, and the config behavior may differ from static to init (calls to the same property name may yield different results).

Still, this seems to be something that users are relying on, so we can support it. I was already planning to move the registration code to the config generator.

@gsmet
Copy link
Member

gsmet commented Sep 6, 2021

The PR fixing this has been reverted for now. A future fix is expected but we have no timeline for it.

@boev
Copy link

boev commented Mar 18, 2022

For me this still happens in quarkus 2.7.1:
<quarkus.platform.version>2.7.1.Final</quarkus.platform.version>

I have a property Class mapped with @ConfigMapping. Injecting the property class inside

public class SomeRequestFilter implements ContainerRequestFilter

Fails the Application with "Could not find mapping for ...."
Injecting the property class anywhere else works.

@radcortez
Copy link
Member

Is your mapping annotated with @StaticInitSafe?

@boev
Copy link

boev commented Mar 21, 2022

Hi @radcortez, annotating my property interface like this:

@ConfigMapping(prefix = "some.properties")
@StaticInitSafe
public interface SomeProperties {
    
}

made it injectable in my public class SomeRequestFilter implements ContainerRequestFilter.

Thank you very much for the quick help.

@holly-cummins
Copy link
Contributor

I found my application would work on startup, but then crash on hot reload, if I marked my config @StaticInitSafe. I guess the config I was looking at really wasn't safe for static init. :)

However, the solution in https://stackoverflow.com/questions/68769397/jar-rs-filter-injection-of-a-cdi-singleton-that-reference-a-configmapping-objec seems to be working for me. Wrapping my config (or the thing that uses it) in @Instance defers the access (I assume?) until everything is nicely initialised, and so there's no crashes.

@radcortez
Copy link
Member

I found my application would work on startup, but then crash on hot reload, if I marked my config @StaticInitSafe. I guess the config I was looking at really wasn't safe for static init. :)

:)

However, the solution in https://stackoverflow.com/questions/68769397/jar-rs-filter-injection-of-a-cdi-singleton-that-reference-a-configmapping-objec seems to be working for me. Wrapping my config (or the thing that uses it) in @Instance defers the access (I assume?) until everything is nicely initialised, and so there's no crashes.

The main issue is that filters are initialized at static init. Some configuration sources are not available at static init, because dependent services are not available yet to retrieve them (think for instance, a database-based config source). The @StaticInitSafe is used to mark config component that is safe to be loaded during static init (does not contain a configuration that required retrieval from a database - not available yet - and because of it fails).

The live reloading might be another issue. I've recently improved the dev reload for configuration in #30964. I hope that helps.

@holly-cummins
Copy link
Contributor

Thanks, @radcortez! Oddly, the configuration that was causing failures if I marked it @StaticInitSafe was quarkus.application.name, so definitely no databases involved. It sounds like #30964 might fix the hot reload issue, so I'll have a try with that once it's in a release to see if I can drop the Instance< wrapper and go back to @StaticInitSafe.

@radcortez
Copy link
Member

Sure, let me know if that fixes it. If not, I'll have a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/config env/windows Impacts Windows machines kind/bug Something isn't working
Projects
None yet
6 participants