Quarkus: mongodb+srv protocol no more working on dev mode since Quarkus 1.3 with Java 11

Created on 30 Apr 2020  Â·  12Comments  Â·  Source: quarkusio/quarkus

Describe the bug
SInce Quarkus 1.3, using a MongoDB connection String with mongodb+srv didn't work anymore on dev mode.
This work fine when launching the JAR file (native mode didn't works for mongo+srv).
This work fine with Quarkus 1.2.
This is a Java 11 and later only issue on dev mode.

Adding the right export to the JVM do the trick but we normally didn't need to as using the JAR file works : --add-exports jdk.naming.dns/com.sun.jndi.dns=java.naming

Actual behavior
It fails with the following stacktrace:

Caused by: com.mongodb.MongoClientException: Unable to support mongodb+srv// style connections as the 'com.sun.jndi.dns.DnsContextFactory' class is not available in this JRE. A JNDI context is required for resolving SRV records.
    at com.mongodb.internal.dns.DefaultDnsResolver.createDnsDirContext(DefaultDnsResolver.java:152)
    at com.mongodb.internal.dns.DefaultDnsResolver.resolveAdditionalQueryParametersFromTxtRecords(DefaultDnsResolver.java:112)
    at com.mongodb.ConnectionString.<init>(ConnectionString.java:382)
    at io.quarkus.mongodb.runtime.AbstractMongoClientProducer.createMongoConfiguration(AbstractMongoClientProducer.java:240)
    at io.quarkus.mongodb.runtime.AbstractMongoClientProducer.createMongoClient(AbstractMongoClientProducer.java:87)
    at io.quarkus.mongodb.runtime.MongoClientProducer.createDefaultMongoClient(MongoClientProducer.zig:37)
    at io.quarkus.mongodb.runtime.MongoClientProducer_ProducerMethod_createDefaultMongoClient_e88f14bf92aae40841e4b513ac764f8acd21873d_Bean.create(MongoClientProducer_ProducerMethod_createDefaultMongoClient_e88f14bf92aae40841e4b513ac764f8acd21873d_Bean.zig:138)
    at io.quarkus.mongodb.runtime.MongoClientProducer_ProducerMethod_createDefaultMongoClient_e88f14bf92aae40841e4b513ac764f8acd21873d_Bean.create(MongoClientProducer_ProducerMethod_createDefaultMongoClient_e88f14bf92aae40841e4b513ac764f8acd21873d_Bean.zig:77)
    at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:80)
    at io.quarkus.arc.impl.ComputingCache$CacheFunction.lambda$apply$0(ComputingCache.java:99)
    at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26)
    at io.quarkus.arc.impl.ComputingCache.getValue(ComputingCache.java:41)
    at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:25)
    at io.quarkus.mongodb.runtime.MongoClientProducer_ProducerMethod_createDefaultMongoClient_e88f14bf92aae40841e4b513ac764f8acd21873d_ClientProxy.arc$delegate(MongoClientProducer_ProducerMethod_createDefaultMongoClient_e88f14bf92aae40841e4b513ac764f8acd21873d_ClientProxy.zig:264)
    at io.quarkus.mongodb.runtime.MongoClientProducer_ProducerMethod_createDefaultMongoClient_e88f14bf92aae40841e4b513ac764f8acd21873d_ClientProxy.getDatabase(MongoClientProducer_ProducerMethod_createDefaultMongoClient_e88f14bf92aae40841e4b513ac764f8acd21873d_ClientProxy.zig:104)
    at org.acme.rest.json.FruitService.getCollection(FruitService.java:44)
    at org.acme.rest.json.FruitService.list(FruitService.java:20)
    at org.acme.rest.json.FruitService_ClientProxy.list(FruitService_ClientProxy.zig:51)
    at org.acme.rest.json.FruitResource.list(FruitResource.java:21)
    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 org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:167)
    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
    at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:621)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:487)
    at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:437)
    at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:362)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:439)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:400)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:374)
    at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:67)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:488)
    ... 20 more
Caused by: javax.naming.NoInitialContextException: Cannot instantiate class: com.sun.jndi.dns.DnsContextFactory [Root exception is java.lang.IllegalAccessException: class javax.naming.spi.NamingManager (in module java.naming) cannot access class com.sun.jndi.dns.DnsContextFactory (in module jdk.naming.dns) because module jdk.naming.dns does not export com.sun.jndi.dns to module java.naming]
    at java.naming/javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:719)
    at java.naming/javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
    at java.naming/javax.naming.InitialContext.init(InitialContext.java:236)
    at java.naming/javax.naming.InitialContext.<init>(InitialContext.java:208)
    at java.naming/javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:101)
    at com.mongodb.internal.dns.DefaultDnsResolver.createDnsDirContext(DefaultDnsResolver.java:150)
    ... 53 more
Caused by: java.lang.IllegalAccessException: class javax.naming.spi.NamingManager (in module java.naming) cannot access class com.sun.jndi.dns.DnsContextFactory (in module jdk.naming.dns) because module jdk.naming.dns does not export com.sun.jndi.dns to module java.naming
    at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:361)
    at java.base/jdk.internal.reflect.Reflection.ensureMemberAccess(Reflection.java:99)
    at java.base/java.lang.Class.newInstance(Class.java:579)
    at java.naming/javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:716)
    ... 58 more

To Reproduce
The issue can be reproduced easily on the mongodb-client integration test:

  • Use Java 11
  • Update application.properties with the following connection String :
quarkus.mongodb.connection-string=mongodb+srv://sarah:[email protected]/test?retryWrites=true&w=majority
  • Launch the application in dev mode: mvn quarkus:dev
  • Access the endpoint: curl localhost:8080/books

Of course, this cluster didn't exist ;) but the test fails before connecting to it.

aremongodb kinbug

Most helpful comment

It just means we will work on a better fix upstream in the SmallRye components.

But we don’t plan to break it :)

Le 5 mai 2020 à 22:37, Abel Salgado Romero notifications@github.com a écrit :

Yes, definitely. The fix is basically a hack and might cause other problems down the road.

I interested in this comment. I tested with 1.4.2 release and it works now, but does this comment mean this may break at some other point or that this is not recommended?

—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub, or unsubscribe.

All 12 comments

/cc @loicmathieu

/cc @gsmet @stuartwdouglas I fear this is a tricky class loader issue as it works in 1.2 and no more on 1.3, it's a dev mode only issue, and the exception is around not finding some class ...

This is a reproducer that can be used instead of the integration test (this is the integration test with the properties file already updated)
mongodb-client.zip

@stuartwdouglas we had two reports in the last 48 hours so if it's a quick fix, it might be a cool one for 1.4.2.

So we can't really fix this at the moment until we fix all the broken class loading in Eclipse Microprofile and Smallrye.

Since JDK 9 service loaders in the JDK now no longer follow the delegation model, instead the services in the platform module are directly exposed, which means you need a direct getParent() relationship to the system CL for these to work. If getParent returns null these can't be loaded.

Unfortunatly some SmallRye and MP specs also don't follow the delegation model, and also use getParent to load classes (instead of letting the ClassLoader do the delegation). When you have an isolated class loader like we have this causes ServiceConfigurationError.

I think the places in our code where this is a problem are:

SmallRye JWT: https://github.com/smallrye/smallrye-jwt/blob/master/implementation/src/main/java/io/smallrye/jwt/auth/principal/JWTCallerPrincipalFactory.java#L75

Reactive Streams Operators: https://github.com/eclipse/microprofile-reactive-streams-operators/pull/130 (fixed but not released)

MP Open API: https://github.com/eclipse/microprofile-open-api/blob/master/spi/src/main/java/org/eclipse/microprofile/openapi/spi/OASFactoryResolver.java#L92

It's possible there are more, these are just the ones I have source downloaded for in intellij.

@kenfinnigan would it be possible to get someone from MP/Smallrye to go through and fix all these, and get releases out? Anything that attempts to load services from the parent CL needs to be fixed.

I might have come up with another workaround, which is to use the platform CL as the parent.

@stuartwdouglas even though you've fixed this in Quarkus, is it better for MP/SRye projects do work towards the fix you mention anyway?

Yes, definitely. The fix is basically a hack and might cause other problems down the road.

Sorry for the noise, I accidentally closed it by merging the unrelated PR

@sberyozkin no, in fact it is already closed by another merged PR ;)

Yes, definitely. The fix is basically a hack and might cause other problems down the road.

I interested in this comment. I tested with 1.4.2 release and it works now, but does this comment mean this may break at some other point or that this is not recommended?

It just means we will work on a better fix upstream in the SmallRye components.

But we don’t plan to break it :)

Le 5 mai 2020 à 22:37, Abel Salgado Romero notifications@github.com a écrit :

Yes, definitely. The fix is basically a hack and might cause other problems down the road.

I interested in this comment. I tested with 1.4.2 release and it works now, but does this comment mean this may break at some other point or that this is not recommended?

—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub, or unsubscribe.

Was this page helpful?
0 / 5 - 0 ratings