[SNMP4J] NullPointerException while resending a GET request

George Tsaloukidis gtsal at intracom.gr
Wed Apr 1 15:11:15 CEST 2009


Dear Frank,

I am using snmp4j version 1.9.3d for executing synchronous snmp GET requests.
My application has many threads, but each thread uses its own org.snmp4j.Snmp instance.
Sometimes I get the following exception:

java.lang.NullPointerException
        at org.snmp4j.Snmp$PendingRequest.pduHandleAssigned(Unknown Source)
        at org.snmp4j.MessageDispatcherImpl.sendPdu(Unknown Source)
        at org.snmp4j.Snmp.sendMessage(Unknown Source)
        at org.snmp4j.Snmp$PendingRequest.run(Unknown Source)
        at java.util.TimerThread.mainLoop(Timer.java:512)
        at java.util.TimerThread.run(Timer.java:462)
Exception in thread "Timer-4877612" java.lang.NullPointerException
        at org.snmp4j.Snmp$PendingRequest.pduHandleAssigned(Unknown Source)
        at org.snmp4j.MessageDispatcherImpl.sendPdu(Unknown Source)
        at org.snmp4j.Snmp.sendMessage(Unknown Source)
        at org.snmp4j.Snmp$PendingRequest.run(Unknown Source)
        at java.util.TimerThread.mainLoop(Timer.java:512)
        at java.util.TimerThread.run(Timer.java:462)

After rebuilding SNMP4J.jar with debug information I saw that the problem was at line 1449 of Snmp.java file:

        long delay = timeoutModel.getRetryTimeout(target.getRetries() -
                                                  retryCount,
                                                  target.getRetries(),
                                                  target.getTimeout());

That means the target object was null while trying to retransmit the request.
That can happen only for two reasons: a) PendingRequest of the retry action created
just after the cancellation of the very first PendingRequest (line 1487) or,
the PendingRequest canceled while inside the pduHandleAssigned() method.
The second case can appear only if the main thread gets that object from the pendingRequests list (line 811).
That means the Timer thread had previously managed to execute the 1440 line and suspended for a while.

The problem is that the send() method (line 793) can call the cancel() operation on a PendingRequest
at any time, without taking into consideration if the TimerThread is executed.

A solution can be to first lock the PendingRequest before calling setFinished() and cancel() methods.
Line 811 should also go after the cancellation of the first request or else if PendingRequest.run() has started,
the newly created PendingRequest is left into the pendingRequests list for ever.
I have tested the above solution and I had no problem.

And something else. At line 810 the wait() method is called.
Sun advices such calls to be wrapped into a while loop
(see http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.8.1 and 
http://java.sun.com/javase/6/docs/api/java/lang/Object.html#wait() links)

while(syncResponse.response == null)
{
   syncResponse.wait();
}

Best regards,

George Tsaloukidis,
Senior Software Engineer
Systems Software Developement
Intracom Telecom S.A


More information about the SNMP4J mailing list