ibatis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jgbut...@apache.org
Subject svn commit: r701431 - in /ibatis/trunk/java/ibatis-2/ibatis-2-core: build/version.properties doc/release.txt src/com/ibatis/sqlmap/engine/execution/SqlExecutor.java src/com/ibatis/sqlmap/engine/mapping/result/ResultObjectFactoryUtil.java
Date Fri, 03 Oct 2008 16:15:38 GMT
Author: jgbutler
Date: Fri Oct  3 09:15:37 2008
New Revision: 701431

URL: http://svn.apache.org/viewvc?rev=701431&view=rev
Log:
Fixes for IBATIS-540: memory leaks in ResultObjectFactoryUtil

Modified:
    ibatis/trunk/java/ibatis-2/ibatis-2-core/build/version.properties
    ibatis/trunk/java/ibatis-2/ibatis-2-core/doc/release.txt
    ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/execution/SqlExecutor.java
    ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/mapping/result/ResultObjectFactoryUtil.java

Modified: ibatis/trunk/java/ibatis-2/ibatis-2-core/build/version.properties
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-2/ibatis-2-core/build/version.properties?rev=701431&r1=701430&r2=701431&view=diff
==============================================================================
--- ibatis/trunk/java/ibatis-2/ibatis-2-core/build/version.properties (original)
+++ ibatis/trunk/java/ibatis-2/ibatis-2-core/build/version.properties Fri Oct  3 09:15:37
2008
@@ -1,5 +1,5 @@
 #Build version info
-#Tue Sep 09 09:43:13 MDT 2008
+#Fri Oct 03 10:04:40 CDT 2008
 version=2.3.4
-buildDate=2008/09/09 09\:43
-buildNum=726
+buildDate=2008/10/03 10\:04
+buildNum=730

Modified: ibatis/trunk/java/ibatis-2/ibatis-2-core/doc/release.txt
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-2/ibatis-2-core/doc/release.txt?rev=701431&r1=701430&r2=701431&view=diff
==============================================================================
--- ibatis/trunk/java/ibatis-2/ibatis-2-core/doc/release.txt (original)
+++ ibatis/trunk/java/ibatis-2/ibatis-2-core/doc/release.txt Fri Oct  3 09:15:37 2008
@@ -5,7 +5,7 @@
 Next Version
 ------------------------------
 
- o 
+ o iBATIS-540 - cleanup result object factory after use to avoid leaks
 
 ------------------------------
  2.3.4

Modified: ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/execution/SqlExecutor.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/execution/SqlExecutor.java?rev=701431&r1=701430&r2=701431&view=diff
==============================================================================
--- ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/execution/SqlExecutor.java
(original)
+++ ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/execution/SqlExecutor.java
Fri Oct  3 09:15:37 2008
@@ -81,6 +81,7 @@
       rows = ps.getUpdateCount();
     } finally {
       closeStatement(statementScope.getSession(), ps);
+      cleanupResultObjectFactory();
     }
     return rows;
   }
@@ -193,6 +194,7 @@
         closeResultSet(rs);
       } finally {
         closeStatement(statementScope.getSession(), ps);
+        cleanupResultObjectFactory();
       }
     }
 
@@ -232,6 +234,7 @@
       retrieveOutputParameters(statementScope, cs, mappings, parameters, null);
     } finally {
       closeStatement(statementScope.getSession(), cs);
+      cleanupResultObjectFactory();
     }
     return rows;
   }
@@ -289,6 +292,7 @@
         closeResultSet(rs);
       } finally {
         closeStatement(statementScope.getSession(), cs);
+        cleanupResultObjectFactory();
       }
     }
   }
@@ -676,7 +680,11 @@
 
   private void setupResultObjectFactory(StatementScope statementScope) {
     SqlMapClientImpl client = (SqlMapClientImpl) statementScope.getSession().getSqlMapClient();
-    ResultObjectFactoryUtil.setResultObjectFactory(client.getResultObjectFactory());
-    ResultObjectFactoryUtil.setStatementId(statementScope.getStatement().getId());
+    ResultObjectFactoryUtil.setupResultObjectFactory(client.getResultObjectFactory(),
+        statementScope.getStatement().getId());
+  }
+  
+  private void cleanupResultObjectFactory() {
+    ResultObjectFactoryUtil.cleanupResultObjectFactory();
   }
 }

Modified: ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/mapping/result/ResultObjectFactoryUtil.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/mapping/result/ResultObjectFactoryUtil.java?rev=701431&r1=701430&r2=701431&view=diff
==============================================================================
--- ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/mapping/result/ResultObjectFactoryUtil.java
(original)
+++ ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/mapping/result/ResultObjectFactoryUtil.java
Fri Oct  3 09:15:37 2008
@@ -84,7 +84,7 @@
   public static Object createObjectThroughFactory(Class clazz) throws InstantiationException,
       IllegalAccessException {
     
-    FactorySettings fs = getFactorySettings();
+    FactorySettings fs = getCurrentFactorySettings();
     
     Object obj;
     if (fs.getResultObjectFactory() == null) {
@@ -124,19 +124,52 @@
     return obj;
   }
   
-  public static void setResultObjectFactory(ResultObjectFactory resultObjectFactory) {
-    getFactorySettings().setResultObjectFactory(resultObjectFactory);
+  /**
+   * This method pushes a new result object factory configuration onto the stack.
+   * We use a stack because the method can be called in a "nested" fashion if there
+   * are sub-selects.  Calls to this method should be equally balanced
+   * with calls to cleanupResultObjectFactory().
+   * 
+   * @param resultObjectFactory
+   * @param statementId
+   */
+  public static void setupResultObjectFactory(ResultObjectFactory resultObjectFactory, String
statementId) {
+    Stack<FactorySettings> fss = (Stack<FactorySettings>) factorySettings.get();
+    if (fss == null) {
+    	fss = new Stack<FactorySettings>();
+    	factorySettings.set(fss);
+    }
+    
+    FactorySettings fs = new FactorySettings();
+    fs.setResultObjectFactory(resultObjectFactory);
+    fs.setStatementId(statementId);
+    fss.push(fs);
   }
   
-  public static void setStatementId(String statementId) {
-    getFactorySettings().setStatementId(statementId);
+  /**
+   * Removes the FactorySettings bound to the current thread to avoid classloader leak issues.
+   * This method pops the top item off the stack, and kills the stack if there
+   * are no items left.
+   */
+  public static void cleanupResultObjectFactory(){
+    Stack<FactorySettings> fss = (Stack<FactorySettings>) factorySettings.get();
+    if (!fss.empty()) {
+    	fss.pop();
+    }
+    
+    if (fss.empty()) {
+    	factorySettings.remove();
+    }
   }
   
-  private static FactorySettings getFactorySettings() {
-    FactorySettings fs = (FactorySettings) factorySettings.get();
-    if (fs == null) {
+  private static FactorySettings getCurrentFactorySettings() {
+    Stack<FactorySettings> fss = (Stack<FactorySettings>) factorySettings.get();
+    FactorySettings fs;
+    if (fss == null || fss.empty()) {
+      // this shouldn't happen if the SqlExecuter is behaving correctly
       fs = new FactorySettings();
-      factorySettings.set(fs);
+    } else {
+      fs = fss.peek();
     }
     
     return fs;



Mime
View raw message