Author: kai
Date: Mon Aug 10 19:40:31 2009
New Revision: 802914
URL: http://svn.apache.org/viewvc?rev=802914&view=rev
Log:
- updated release notes
IBATIS-595 (IllegalAccessException if a default-method is called in Lazy-Loaded
Proxy objects)
- applied the patch with minor changes (renamed the test beans)
Added:
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/EnhancedLazyResultLoaderTest.java
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/test/
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/test/Bean1.java
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/test/Bean2.java
Modified:
ibatis/trunk/java/ibatis-2/ibatis-2-core/doc/release.txt
ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/mapping/result/loader/EnhancedLazyResultLoader.java
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=802914&r1=802913&r2=802914&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 Mon Aug 10
19:40:31 2009
@@ -5,6 +5,8 @@
Next Version
------------------------------
+ o IBATIS-618 - Provide SQLExecutor's an opportunity to initialise state at
initialization time
+ o IBATIS-595 - IllegalAccessException if a default-method is called in
Lazy-Loaded Proxy objects
o iBATIS-540 - cleanup result object factory after use to avoid leaks
o iBATIS-436 - Defaults for <settings/> element aren't applied if it doesn't
exist: changed default values of lazyLoadingEnabled, cacheModelsEnabled and
statementCacheEnabled to true if no <settings /> element present
o IBATIS-508 - Lock occurs when heavy traffic: removed double synchronization
Modified:
ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/mapping/result/loader/EnhancedLazyResultLoader.java
URL:
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/mapping/result/loader/EnhancedLazyResultLoader.java?rev=802914&r1=802913&r2=802914&view=diff
==============================================================================
---
ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/mapping/result/loader/EnhancedLazyResultLoader.java
(original)
+++
ibatis/trunk/java/ibatis-2/ibatis-2-core/src/com/ibatis/sqlmap/engine/mapping/result/loader/EnhancedLazyResultLoader.java
Mon Aug 10 19:40:31 2009
@@ -15,20 +15,19 @@
*/
package com.ibatis.sqlmap.engine.mapping.result.loader;
-import com.ibatis.common.beans.ClassInfo;
-
-import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl;
-import com.ibatis.sqlmap.engine.type.DomTypeMarker;
-import net.sf.cglib.proxy.Enhancer;
-import net.sf.cglib.proxy.InvocationHandler;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Set;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.LazyLoader;
+import net.sf.cglib.proxy.NoOp;
+
+import com.ibatis.common.beans.ClassInfo;
+import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl;
+import com.ibatis.sqlmap.engine.type.DomTypeMarker;
+
/**
* Class to lazily load results into objects (uses CGLib to improve
performance)
*/
@@ -63,7 +62,7 @@
}
- private static class EnhancedLazyResultLoaderImpl implements
InvocationHandler {
+ private static class EnhancedLazyResultLoaderImpl implements LazyLoader {
protected SqlMapClientImpl client;
@@ -112,34 +111,19 @@
}
}
- public Object invoke(Object o, Method method, Object[] objects) throws
Throwable {
- if ("finalize".hashCode() == method.getName().hashCode()
- && "finalize".equals(method.getName())) {
- return null;
- } else {
- loadObject();
- if (resultObject != null) {
- try {
- return method.invoke(resultObject, objects);
- } catch (Throwable t) {
- throw ClassInfo.unwrapThrowable(t);
- }
- } else {
- return null;
- }
- }
- }
-
- private synchronized void loadObject() {
- if (!loaded) {
- try {
- loaded = true;
- resultObject = ResultLoader.getResult(client, statementName,
parameterObject, targetType);
- } catch (SQLException e) {
- throw new RuntimeException("Error lazy loading result. Cause: " + e,
e);
- }
- }
- }
+ public Object loadObject() throws Exception {
+ try {
+ Object result = ResultLoader.getResult(client,
statementName, parameterObject, targetType);
+ if (result == null) {
+ // if no result is available return a proxy
with a default object is returned
+ // because the loadObject() method must not
return null
+ result = Enhancer.create(targetType,
NoOp.INSTANCE);
+ }
+ return result;
+ } catch (SQLException e) {
+ throw new RuntimeException("Error lazy loading result.
Cause: " + e, e);
+ }
+ }
}
Added:
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/EnhancedLazyResultLoaderTest.java
URL:
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/EnhancedLazyResultLoaderTest.java?rev=802914&view=auto
==============================================================================
---
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/EnhancedLazyResultLoaderTest.java
(added)
+++
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/EnhancedLazyResultLoaderTest.java
Mon Aug 10 19:40:31 2009
@@ -0,0 +1,77 @@
+package com.ibatis.sqlmap.engine.mapping.result.loader;
+
+import java.sql.SQLException;
+
+import com.ibatis.sqlmap.engine.impl.SqlMapClientImpl;
+import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate;
+import com.ibatis.sqlmap.engine.mapping.result.loader.test.Bean1;
+import com.ibatis.sqlmap.engine.mapping.result.loader.test.Bean2;
+
+import junit.framework.TestCase;
+
+public class EnhancedLazyResultLoaderTest extends TestCase {
+
+ /**
+ * Test if a method in a proxied object can access a default method of
+ * another class in the same package with default access modifier.
+ * <p>
+ * Depending of the implementation of the Cglib-proxy the access will
+ * throw an IllegalAccessException.
+ */
+ public void testProxyMethodAccess() throws SQLException {
+ SqlMapClientImpl client = setupMockSqlMapClientImpl();
+
+ EnhancedLazyResultLoader loader = new
EnhancedLazyResultLoader(client , "bean2", null, Bean2.class);
+ Bean2 bean2 = (Bean2) loader.loadResult();
+
+ // cglib might throw an IllegalAccessException
+ bean2.testDefaultAccess();
+ }
+
+ /**
+ * Test if a proxy for a null nevertheless dispatch to a default object.
+ */
+ public void testNullProxy() throws SQLException {
+ SqlMapClientImpl client = setupMockSqlMapClientImpl();
+
+ EnhancedLazyResultLoader loader = new
EnhancedLazyResultLoader(client , "bean3", null, TestBean3.class);
+ TestBean3 bean = (TestBean3) loader.loadResult();
+
+ assertEquals("foobar", bean.getText());
+ }
+
+
+ /**
+ * Mock a {...@link SqlMapClientImpl} which returns a {...@link Bean1}
for the id
+ * <code>bean1</code> and {...@link Bean2} for id <code>bean2</code>.
+ */
+ private SqlMapClientImpl setupMockSqlMapClientImpl() {
+ SqlMapExecutorDelegate delegate = new SqlMapExecutorDelegate();
+ SqlMapClientImpl client = new SqlMapClientImpl(delegate ) {
+ @Override
+ public Object queryForObject(String id, Object
paramObject) throws SQLException {
+ if ("bean1".equals(id)) {
+ return new Bean1();
+ } else if ("bean2".equals(id)) {
+ Bean2 bean = new Bean2();
+ EnhancedLazyResultLoader loader = new
EnhancedLazyResultLoader(this, "bean1", null, Bean1.class);
+ bean.setBean1((Bean1)
loader.loadResult());
+ return bean;
+ } else if ("bean3".equals(id)) {
+ return null;
+ }
+ fail();
+ return null;
+ }
+ };
+ return client;
+ }
+
+ public static class TestBean3 {
+
+ public String getText() {
+ return "foobar";
+ }
+
+ }
+}
Added:
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/test/Bean1.java
URL:
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/test/Bean1.java?rev=802914&view=auto
==============================================================================
---
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/test/Bean1.java
(added)
+++
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/test/Bean1.java
Mon Aug 10 19:40:31 2009
@@ -0,0 +1,9 @@
+package com.ibatis.sqlmap.engine.mapping.result.loader.test;
+
+public class Bean1 {
+
+ void defaultMethod() {
+ // default-access method
+ }
+
+}
Added:
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/test/Bean2.java
URL:
http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/test/Bean2.java?rev=802914&view=auto
==============================================================================
---
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/test/Bean2.java
(added)
+++
ibatis/trunk/java/ibatis-2/ibatis-2-core/test/com/ibatis/sqlmap/engine/mapping/result/loader/test/Bean2.java
Mon Aug 10 19:40:31 2009
@@ -0,0 +1,16 @@
+package com.ibatis.sqlmap.engine.mapping.result.loader.test;
+
+public class Bean2 {
+
+ private Bean1 bean1;
+
+
+ public void setBean1(Bean1 bean1) {
+ this.bean1 = bean1;
+ }
+
+ public void testDefaultAccess() {
+ bean1.defaultMethod();
+ }
+
+}