You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2008/01/21 10:43:27 UTC

svn commit: r613815 - /db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericActivationHolder.java

Author: kahatlen
Date: Mon Jan 21 01:43:22 2008
New Revision: 613815

URL: http://svn.apache.org/viewvc?rev=613815&view=rev
Log:
DERBY-3260: NullPointerException caused by race condition in GenericActivationHolder

Hold the synchronization lock on the GenericPreparedStatement until
the activation class has been retrieved. This prevents other threads
from setting the activation class to null before we have retrieved it,
and thereby prevents the NPE.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericActivationHolder.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericActivationHolder.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericActivationHolder.java?rev=613815&r1=613814&r2=613815&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericActivationHolder.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/GenericActivationHolder.java Mon Jan 21 01:43:22 2008
@@ -255,9 +255,20 @@
 			if (gc != ps.getActivationClass())
 			{
 
+                GeneratedClass newGC;
+
 				// ensure the statement is valid by rePreparing it.
-				ps.rePrepare(getLanguageConnectionContext());
-				
+                // DERBY-3260: If someone else reprepares the statement at the
+                // same time as we do, there's a window between the calls to
+                // rePrepare() and getActivationClass() when the activation
+                // class can be set to null, leading to NullPointerException
+                // being thrown later. Therefore, synchronize on ps to close
+                // the window.
+                synchronized (ps) {
+                    ps.rePrepare(getLanguageConnectionContext());
+                    newGC = ps.getActivationClass();
+                }
+
 				/*
 				** If we get here, it means the PreparedStatement has been
 				** recompiled.  Get a new Activation and check whether the
@@ -265,8 +276,6 @@
 				** from the old Activation to the new one, and make that the
 				** current Activation.  If not, throw an exception.
 				*/
-				GeneratedClass		newGC = ps.getActivationClass();
-
 				BaseActivation		newAC = (BaseActivation) newGC.newInstance(lcc);
 
 				DataTypeDescriptor[]	newParamTypes = ps.getParameterTypes();