Derby
  1. Derby
  2. DERBY-5736

NullPointerException in GenericTriggerExecutor.executeSPS() caused by OutOfMemoryError

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 10.9.1.0
    • Fix Version/s: 10.8.3.3, 10.9.1.0
    • Component/s: SQL
    • Labels:
      None
    • Environment:
      java version "1.7.0_02"
      Java(TM) SE Runtime Environment (build 1.7.0_02-b13)
      Java HotSpot(TM) Server VM (build 22.0-b10, mixed mode)

      Oracle Solaris 11.1 X86

      Description

      If I run TriggerTest with the flags -server and -Xmx150M passed to the JVM, I fairly consistently see a NPE being thrown:

      java.lang.NullPointerException
      at org.apache.derby.impl.sql.execute.GenericTriggerExecutor.executeSPS(GenericTriggerExecutor.java:221)
      at org.apache.derby.impl.sql.execute.RowTriggerExecutor.fireTrigger(RowTriggerExecutor.java:114)
      at org.apache.derby.impl.sql.execute.TriggerEventActivator.notifyEvent(TriggerEventActivator.java:281)
      at org.apache.derby.impl.sql.execute.UpdateResultSet.fireAfterTriggers(UpdateResultSet.java:818)
      at org.apache.derby.impl.sql.execute.UpdateResultSet.open(UpdateResultSet.java:280)
      at org.apache.derby.impl.sql.GenericPreparedStatement.executeStmt(GenericPreparedStatement.java:443)
      at org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:324)
      at org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1242)
      at org.apache.derby.impl.jdbc.EmbedPreparedStatement.executeStatement(EmbedPreparedStatement.java:1715)
      at org.apache.derby.impl.jdbc.EmbedPreparedStatement.execute(EmbedPreparedStatement.java:1370)
      at org.apache.derbyTesting.functionTests.tests.lang.TriggerTest.testBlobInTriggerTable(TriggerTest.java:880)
      at org.apache.derbyTesting.functionTests.tests.lang.TriggerTest.testBlobInTriggerTable(TriggerTest.java:779)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:601)
      at junit.framework.TestCase.runTest(TestCase.java:164)
      at junit.framework.TestCase.runBare(TestCase.java:130)
      at org.apache.derbyTesting.junit.BaseTestCase.runBare(BaseTestCase.java:113)
      at junit.framework.TestResult$1.protect(TestResult.java:106)
      at junit.framework.TestResult.runProtected(TestResult.java:124)
      at junit.framework.TestResult.run(TestResult.java:109)
      at junit.framework.TestCase.run(TestCase.java:120)
      at junit.framework.TestSuite.runTest(TestSuite.java:230)
      at junit.framework.TestSuite.run(TestSuite.java:225)
      at junit.extensions.TestDecorator.basicRun(TestDecorator.java:24)
      at junit.extensions.TestSetup$1.protect(TestSetup.java:21)
      at junit.framework.TestResult.runProtected(TestResult.java:124)
      at junit.extensions.TestSetup.run(TestSetup.java:25)
      at org.apache.derbyTesting.junit.BaseTestSetup.run(BaseTestSetup.java:57)
      at junit.textui.TestRunner.doRun(TestRunner.java:121)
      at junit.textui.TestRunner.start(TestRunner.java:185)
      at junit.textui.TestRunner.main(TestRunner.java:143)

      In derby.log, there is an OOME right before the NPE:

      java.lang.OutOfMemoryError: Java heap space
      at org.apache.derby.impl.jdbc.LOBStreamControl.updateData(LOBStreamControl.java:154)
      at org.apache.derby.impl.jdbc.LOBStreamControl.write(LOBStreamControl.java:247)
      at org.apache.derby.impl.jdbc.LOBStreamControl.<init>(LOBStreamControl.java:89)
      at org.apache.derby.impl.jdbc.EmbedBlob.<init>(EmbedBlob.java:189)
      at org.apache.derby.impl.jdbc.EmbedResultSet.getBlob(EmbedResultSet.java:4072)
      at org.apache.derby.impl.jdbc.EmbedResultSet.getObject(EmbedResultSet.java:1704)
      at org.apache.derby.exe.ac56961bb1x0137x0d04x3d17x00005ffb0f6356.e0(Unknown Source)
      at org.apache.derby.impl.services.reflect.DirectCall.invoke(ReflectGeneratedClass.java:139)
      at org.apache.derby.impl.sql.execute.RowResultSet.getNextRowCore(RowResultSet.java:148)
      at org.apache.derby.impl.sql.execute.DMLWriteResultSet.getNextRowCore(DMLWriteResultSet.java:127)
      at org.apache.derby.impl.sql.execute.InsertResultSet.open(InsertResultSet.java:507)
      at org.apache.derby.impl.sql.GenericPreparedStatement.executeStmt(GenericPreparedStatement.java:443)
      at org.apache.derby.impl.sql.GenericPreparedStatement.executeSubStatement(GenericPreparedStatement.java:313)
      at org.apache.derby.impl.sql.execute.GenericTriggerExecutor.executeSPS(GenericTriggerExecutor.java:176)
      at org.apache.derby.impl.sql.execute.RowTriggerExecutor.fireTrigger(RowTriggerExecutor.java:114)
      (...)

      The code that fails with NPE, is this call to cleanupOnError() in a catch block in GenericTriggerExecutor.executeSPS():

      /* retrieve the current active SC */
      StatementContext sc = lcc.getStatementContext();

      /* make sure that the cleanup is on the new SC */
      if (active_sc != sc)

      { sc.cleanupOnError(e); }
      1. d5736-1a.diff
        2 kB
        Knut Anders Hatlen

        Issue Links

          Activity

          Hide
          Knut Anders Hatlen added a comment -

          It looks like lcc.getStatementContext() returns null if the trigger action failed with OOME, because the context stack has already been cleaned up at a lower level in the finally clause of EmbedResultSet.getBlob().

          Guarding the call to sc.cleanupOnError(e) with a check for sc!=null seems to fix the problem. That is, the test starts failing with the underlying OutOfMemoryError instead of a NullPointerException trying to clean up after the OOME.

          Show
          Knut Anders Hatlen added a comment - It looks like lcc.getStatementContext() returns null if the trigger action failed with OOME, because the context stack has already been cleaned up at a lower level in the finally clause of EmbedResultSet.getBlob(). Guarding the call to sc.cleanupOnError(e) with a check for sc!=null seems to fix the problem. That is, the test starts failing with the underlying OutOfMemoryError instead of a NullPointerException trying to clean up after the OOME.
          Hide
          Knut Anders Hatlen added a comment -

          Attaching a patch that changes the error handler so it only attempts to clean up the statement context if it is non-null. This should only affect the cases where the error handler would otherwise fail with a NullPointerException that would mask the original error.

          Running the regression test suites.

          Show
          Knut Anders Hatlen added a comment - Attaching a patch that changes the error handler so it only attempts to clean up the statement context if it is non-null. This should only affect the cases where the error handler would otherwise fail with a NullPointerException that would mask the original error. Running the regression test suites.
          Hide
          Knut Anders Hatlen added a comment -

          Regression tests passed.

          Show
          Knut Anders Hatlen added a comment - Regression tests passed.
          Hide
          Kristian Waagan added a comment -

          The fix looks reasonable to me.
          It doesn't make sense to attempt to clean up if there is no context.

          Show
          Kristian Waagan added a comment - The fix looks reasonable to me. It doesn't make sense to attempt to clean up if there is no context.
          Hide
          Knut Anders Hatlen added a comment -

          Thanks, Kristian!
          Committed revision 1335418.

          Show
          Knut Anders Hatlen added a comment - Thanks, Kristian! Committed revision 1335418.
          Hide
          Kathey Marsden added a comment -

          Temporarily assign to myself for backport.

          Show
          Kathey Marsden added a comment - Temporarily assign to myself for backport.
          Hide
          ASF subversion and git services added a comment -

          Commit 1509434 from Kathey Marsden in branch 'code/branches/10.8'
          [ https://svn.apache.org/r1509434 ]

          DERBY-5736 NullPointerException in GenericTriggerExecutor.executeSPS() caused by OutOfMemoryError

          merge revision 1335418 from trunk to 10.8
          Contributed by Knut Anders Hatlen

          Show
          ASF subversion and git services added a comment - Commit 1509434 from Kathey Marsden in branch 'code/branches/10.8' [ https://svn.apache.org/r1509434 ] DERBY-5736 NullPointerException in GenericTriggerExecutor.executeSPS() caused by OutOfMemoryError merge revision 1335418 from trunk to 10.8 Contributed by Knut Anders Hatlen
          Hide
          Kathey Marsden added a comment -

          Assigning back after backport.

          Show
          Kathey Marsden added a comment - Assigning back after backport.

            People

            • Assignee:
              Knut Anders Hatlen
              Reporter:
              Knut Anders Hatlen
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development