From: | Kris Jurka <books(at)ejurka(dot)com> |
---|---|
To: | Morten Andersen <moa-ml(at)instadia(dot)net> |
Cc: | pgsql-jdbc(at)postgresql(dot)org |
Subject: | Re: Unexpected NullPointerException in "processDeadParsedQueries()" |
Date: | 2007-01-04 18:24:27 |
Message-ID: | Pine.BSO.4.64.0701041309320.24201@leary2.csoft.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | 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
From | Date | Subject | |
---|---|---|---|
Next Message | Kris Jurka | 2007-01-04 18:27:00 | Re: Support for DatabaseMetadata: getCatalogName, getTableName, |
Previous Message | Kris Jurka | 2007-01-04 18:03:55 | Re: Driver Bug |