Re: Unexpected NullPointerException in "processDeadParsedQueries()" - Mailing list pgsql-jdbc

From Kris Jurka
Subject Re: Unexpected NullPointerException in "processDeadParsedQueries()"
Date
Msg-id Pine.BSO.4.64.0701041309320.24201@leary2.csoft.net
Whole thread Raw
In response to Unexpected NullPointerException in "processDeadParsedQueries()" - suggested fix  (Morten Andersen <moa-ml@instadia.net>)
Responses Re: Unexpected NullPointerException in "processDeadParsedQueries()"
List pgsql-jdbc

On Wed, 20 Dec 2006, Morten Andersen wrote:

> In a multithreaded application I just got an unexpected NullPointerException
> from the depth's of the JDBC-drivers cleanup routine of parsed queries.
>

Is this something you can reproduce somewhat regularly or something that
just happened once?

> During a batch-execution of a trivial PreparedStatement that generally works
> fine I got the NullPointerException below:
>
> Exception in thread "Thread-5" java.lang.NullPointerException
>        at org.postgresql.core.Utils.encodeUTF8(Utils.java:54)
>        at
> org.postgresql.core.v3.QueryExecutorImpl.sendCloseStatement(QueryExecutorImpl.java:982)
>        at
> org.postgresql.core.v3.QueryExecutorImpl.processDeadParsedQueries(QueryExecutorImpl.java:1104)
>        at
>
> I have been browsing the CVS-repository and I think the code that generates
> this is the processDeadParsedQueries() below:
>
> private void processDeadParsedQueries() throws IOException {
>  PhantomReference deadQuery;
>  while ((deadQuery = (PhantomReference)parsedQueryCleanupQueue.poll()) !=
> null)
>  {
>    String statementName = (String)parsedQueryMap.remove(deadQuery); <---
> RETURNS null?
>    sendCloseStatement(statementName);  <--- TRIGGERS NullPointerException
>    deadQuery.clear();
>  }
> }
>
> I inserted the comments with "<---".
>
> The reaon why it is possible for the parsedQueryMap to return a null
> statementName for the deadQuery key is quite a puzzle to me. Mostly I can
> only think of two reasons:
>
> 1) The statementName for the deadQuery has already been removed. Given the
> code for registerParsedQuery() and processDeadParsedQueries() I can't see how
> this should be possible, as the java.lang.ref.ReferenceQueue is thread-safe
> (it doesn't say so in the API documentation, but that is what you would
> expect, and a quick glance at the JDK source also indicates that this is the
> case).
>
> 2) The use of HashMap for the parsedQueryMap could be a problem in a
> multithreaded application, since it is not thread-safe? So a wild guess is
> that the thread executing the processDeadParsedQueries() does not "see" the
> value that was added to the hashmap by another thread in the
> registerParsedQuery.
>

Neither of these look particularly likely to me.  All entry points to
QueryExecutorImpl that access these items are synchronized so I don't
think the thread safety of the individual items are an issue.

Is your application multi-threaded and using a Connection per thread or
does it use multiple threads per connection?  If using Connection per
thread it's even harder to believe this is a thread safety issue because
you'll have a QueryExecutorImpl per Connection.

Kris Jurka

pgsql-jdbc by date:

Previous
From: Kris Jurka
Date:
Subject: Re: Driver Bug
Next
From: Kris Jurka
Date:
Subject: Re: Support for DatabaseMetadata: getCatalogName, getTableName,