[JAVA-522] Getting Null Pointer Exception in Mongo Java Driver Created: 15/Feb/12  Updated: 18/Jun/12  Resolved: 05/Apr/12

Status: Closed
Project: Java Driver
Component/s: API
Affects Version/s: 2.7.3
Fix Version/s: 2.8.0

Type: Bug Priority: Major - P3
Reporter: Steve Owens Assignee: Jeffrey Yemin
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Fedora RHEL5.



 Description   

One of our production servers is throwing the following exception stack trace and we would like to elicit help in determining what might be the root cause of the error. The interesting parts of the stakc trace are:

ava.lang.NullPointerException
at com.mongodb.CommandResult.getException(CommandResult.java:64)
at com.mongodb.CommandResult.throwOnError(CommandResult.java:116)
at com.mongodb.DBPort.checkAuth(DBPort.java:308)

Any thoughts on the root cause possibilities? The error is intermitent and not consistent.

Full stack trace below:

2012-02-14 17:34:47,719 ERROR org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:274) [http-8080-exec-4] - Servlet.service() for servlet spring
threw exception
java.lang.NullPointerException
at com.mongodb.CommandResult.getException(CommandResult.java:64)
at com.mongodb.CommandResult.throwOnError(CommandResult.java:116)
at com.mongodb.DBPort.checkAuth(DBPort.java:308)
at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:201)
at com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:303)
at com.mongodb.DBCursor._check(DBCursor.java:360)
at com.mongodb.DBCursor._hasNext(DBCursor.java:490)
at com.mongodb.DBCursor.hasNext(DBCursor.java:515)
at org.springframework.data.document.mongodb.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1425)
at org.springframework.data.document.mongodb.MongoTemplate.doFind(MongoTemplate.java:1186)
at org.springframework.data.document.mongodb.MongoTemplate.find(MongoTemplate.java:587)
at org.springframework.data.document.mongodb.repository.AbstractMongoQuery$Execution.readCollection(AbstractMongoQuery.java:106)
at org.springframework.data.document.mongodb.repository.AbstractMongoQuery$CollectionExecution.execute(AbstractMongoQuery.java:125)
at org.springframework.data.document.mongodb.repository.AbstractMongoQuery.execute(AbstractMongoQuery.java:80)
at org.springframework.data.repository.support.RepositoryFactorySupport$QueryExecuterMethodInterceptor.invoke(RepositoryFactorySupport.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy25.findAllAPIsWithUserIdAndRole(Unknown Source)
at com.disney.tss.ft.cms.service.APIService.getAllAppsForOwner(APIService.java:786)
at com.disney.tss.ft.cms.controller.APIController.getAllAppsForOwner(APIController.java:363)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.disney.tss.ft.apimgmt.AuthenticationEnforcementFilter.doFilter(AuthenticationEnforcementFilter.java:101)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.disney.tss.ft.apimgmt.PSKAuthenticationFilter.doFilter(PSKAuthenticationFilter.java:112)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.disney.tss.ft.apimgmt.PortalOauthFilter.doFilter(PortalOauthFilter.java:106)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at com.disney.tomcat.GreenCookieValve.invoke(Unknown Source)
at com.disney.tomcat.RequestThrottleValve.invoke(Unknown Source)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11NioProcessor.process(Http11NioProcessor.java:880)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:719)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:2081)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)



 Comments   
Comment by Jeffrey Yemin [ 18/Jun/12 ]

Closing for 2.8.0 release.

Comment by Jeffrey Yemin [ 05/Apr/12 ]

I fixed the NPE. For the underlying server error that's being masked by this bug, please follow up on one of the support channels.

Comment by auto [ 12/Mar/12 ]

Author:

{u'login': u'jyemin', u'email': u'jeff.yemin@10gen.com', u'name': u'Jeff Yemin'}

Message: JAVA-522: Add constructor to CommandResult that takes a command. Fix NPE when command is null
Branch: master
https://github.com/mongodb/mongo-java-driver/commit/b6388774f33f1d1b89055f2aa8481d2b0689ec1e

Comment by Steve Owens [ 23/Feb/12 ]

Still trying to get server logs showing some kind of errors in conjunction with this issue. I haven't forgotten this issue.

Comment by Steve Owens [ 15/Feb/12 ]

I will try to get them for you tomorrow.

Comment by Jeffrey Yemin [ 15/Feb/12 ]

Yes, I meant server logs.

Comment by Steve Owens [ 15/Feb/12 ]

Some additional information before I go home for the evening. The environment in which this is occuring is set up with multiple mongo shards with multiple mongo instances in each shards replica set. Given what I was reading in the JAVA-397 jira, and from what I can see in the CheckAuth function in DBPort, is it possible that getnonce and authenticate are being issued to different servers?

301        CommandResult res = runCommand( db , new BasicDBObject( "getnonce" , 1 ) );
302        res.throwOnError();
303        
304        DBObject temp = db._authCommand( res.getString( "nonce" ) );
305        
306        res = runCommand( db , temp );
307
308        res.throwOnError();

Especially when evidenced only in situations of relatively high load.

Comment by Steve Owens [ 15/Feb/12 ]

I presume you are talking about the mongo db server logs and not the server logs of the server where the mongo-java-driver is being used correct?

Comment by Steve Owens [ 15/Feb/12 ]

Will request the server logs but probably won't get them till tomorrow.

Comment by Steve Owens [ 15/Feb/12 ]

I found the following related jira issues:
https://jira.mongodb.org/browse/JAVA-397

Related articles:
http://www.mongodb.org/display/DOCS/Implementing+Authentication+in+a+Driver
http://groups.google.com/group/mongodb-user/msg/834d0b80e4168849

Comment by Jeffrey Yemin [ 15/Feb/12 ]

Can you check the server logs for any errors?

Comment by Jeffrey Yemin [ 15/Feb/12 ]

Looks like a bug in DPPort that's generating the NPE, which is masking the server error. The _cmd field is what's null.

Comment by Steve Owens [ 15/Feb/12 ]

Digging further looks like the issue is in

CommandResult.java:64 at:
" String cmdName = _cmd.keySet().iterator().next();"

either _cmd, or _cmd.keySet() or _cmd.keySet().iterator() is null.

Is this an issue that has been fixed in a subsequent release of mongo-java-driver?

public MongoException getException(){
        if ( !ok() ) {
            String cmdName = _cmd.keySet().iterator().next();
 
            StringBuilder buf = new StringBuilder( "command failed [" );
            buf.append( "command failed [" ).append( cmdName ).append( "] " );
            buf.append( toString() );
 
            return new CommandFailure( this , buf.toString() );
        } else {
            // GLE check
            if ( hasErr() ) {
                Object foo = get( "err" );
 
                int code = getCode();
 
                String s = foo.toString();
                if ( code == 11000 || code == 11001 || s.startsWith( "E11000" ) || s.startsWith( "E11001" ) )
                    return new MongoException.DuplicateKey( code , s );
 
                return new MongoException( code , s );
            }
        }
        
        //all good, should never get here.
        return null;

Comment by Steve Owens [ 15/Feb/12 ]

I checked the source and the lines relevant to the null pointer specifically line 308 are as follows. What might cause such a null pointer to occur?

291    void checkAuth( DB db ) throws IOException {
292        if ( db._username == null ){
293            if ( db._name.equals( "admin" ) )
294                return;
295            checkAuth( db._mongo.getDB( "admin" ) );
296            return;
297        }
298        if ( _authed.containsKey( db ) )
299            return;
300        
301        CommandResult res = runCommand( db , new BasicDBObject( "getnonce" , 1 ) );
302        res.throwOnError();
303        
304        DBObject temp = db._authCommand( res.getString( "nonce" ) );
305        
306        res = runCommand( db , temp );
307
308        res.throwOnError();
309        _authed.put( db , true );
400    }

Comment by Steve Owens [ 15/Feb/12 ]

Sepcific version of mongo-java-driver is mongo-java-driver-2.6.5.jar as pulled in by maven the git-hash for the jar file is: a123456f244cd3770f2c6ab78380e6f81fc272f6

Generated at Thu Feb 08 08:52:29 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.