-
Type: Question
-
Resolution: Done
-
Priority: Major - P3
-
None
-
Affects Version/s: None
-
Component/s: Configuration
-
None
Summary
I'm attempting to create com.mongodb.client.MongoClient instances using JNDI. The com.mongodb.client.MongoClientFactory is creating com.mongodb.client.internal.MongoClientImpl instances instead.
This used to work with the legacy driver (using com.mongodb.MongoClient and com.mongodb.client.jndi.MongoClientFactory).
Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).
MongoDB Java driver 4.9.1 (also tried 4.3.4 and 4.6.1)
MongoDB 4.4 (Atlas hosted by mongodb.com), replica set
Tomcat 9.0.73
Jersey 1.19.3
Java 8
How to Reproduce
My server.xml contains the following:
<GlobalNamingResources>
<Resource name="mongodb/GlobalMongoClient"
auth="Container"
type="com.mongodb.client.MongoClient"
closeMethod="close"
factory="com.mongodb.client.MongoClientFactory"
singleton="true"
connectionString="{{ mongo_db | escape }}"
maxTotal="100"
maxIdle="10"
minIdle="2"
/></GlobalNamingResources>
My context.xml contains the following:
<ResourceLink name="mongodb/MyMongoClient"
global="mongodb/GlobalMongoClient"
type="com.mongodb.client.MongoClient"/>
I copy the following files to the Tomcat global lib directory before loading the application:
- mongodb-driver-sync-4.9.1.jar
- mongodb-driver-core-4.9.1.jar
- slf4j-api-1.7.25.jar
- slf4j-log4j12-1.7.25.jar
- log4j-1.2.17.jar
- bson-4.9.1.jar
- bson-record-codec-4.9.1.jar
In my Java application, I use the following code to obtain a MongoClient:
final MongoClient mongoClient =
InitialContext.doLookup("java:comp/env/mongodb/MyMongoClient");
When I load the application in Tomcat, everything seems fine, but when I send an http request to the server, I get the following error in the Tomcat logs:
02-May-2023 22:27:15.746 WARNING [http-nio-127.0.0.1-8080-exec-2] org.apache.naming.NamingContext.lookup Unexpected exception resolving reference java.lang.IllegalArgumentException: The local resource link [MyMongoClient] that refers to global resource [mongodb/GlobalMongoClient] was expected to return an instance of [com.mongodb.client.MongoClient] but returned an instance of [com.mongodb.client.internal.MongoClientImpl] at org.apache.naming.factory.ResourceLinkFactory.getObjectInstance(ResourceLinkFactory.java:158) at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:332)
at org.apache.naming.NamingContext.lookup(NamingContext.java:864) at org.apache.naming.NamingContext.lookup(NamingContext.java:158)
at org.apache.naming.NamingContext.lookup(NamingContext.java:850) at org.apache.naming.NamingContext.lookup(NamingContext.java:158)
at org.apache.naming.NamingContext.lookup(NamingContext.java:850) at org.apache.naming.NamingContext.lookup(NamingContext.java:158) at org.apache.naming.NamingContext.lookup(NamingContext.java:850)
at org.apache.naming.NamingContext.lookup(NamingContext.java:172) at org.apache.naming.SelectorContext.lookup(SelectorContext.java:161)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at javax.naming.InitialContext.doLookup(InitialContext.java:290)
at com.legendpower.DBInput.<init>(DBInput.java:35)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.sun.jersey.server.spi.component.ResourceComponentConstructor._construct(ResourceComponentConstructor.java:245)
at com.sun.jersey.server.spi.component.ResourceComponentConstructor.construct(ResourceComponentConstructor.java:233)
at com.sun.jersey.server.impl.resource.PerRequestFactory$PerRequest._getInstance(PerRequestFactory.java:182)
at com.sun.jersey.server.impl.resource.PerRequestFactory$AbstractPerRequest.getInstance(PerRequestFactory.java:144)
at com.sun.jersey.server.impl.application.WebApplicationContext.getResource(WebApplicationContext.java:239)
at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:83)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1542)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1473)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:558)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:733)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:779)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at com.legendpower.GuiloadFilter.doFilter(GuiloadFilter.java:36)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:750)
Additional Background
Using this code to load the MongoClient via JNDI worked with mongo-java-driver version 3.12.8 and MongoDB 4.2, using the `com.mongodb.client.jndi.MongoClientFactory` resource factory to create the `com.mongodb.client.MongoClient` resource.
I have guessed at some of the configuration above, because the JNDI documentation appears to be out of date as of driver version 4.3 (the oldest version still online). I filed a separate bug about that here:
https://jira.mongodb.org/browse/DOCS-16093
I tried a number of variations but couldn't get it to work. If I'm using it incorrectly, I would be happy to be corrected.