rdonkin 2002/09/22 14:45:35
Modified: beanutils/src/java/org/apache/commons/beanutils
MethodUtils.java
beanutils/src/test/org/apache/commons/beanutils
MethodUtilsTestCase.java
Added: beanutils/src/test/org/apache/commons/beanutils/priv
PackageBean.java PublicSubBean.java
Log:
Added workaround for jvm issue with accessing public methods coded in default access
superclasses via reflaction from a public access subclass instance. This workaround
will will most likely fail if the code is run with right security permissions.
Workaround suggested by Ben Walding.
Revision Changes Path
1.14 +55 -0
jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/MethodUtils.java
Index: MethodUtils.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/beanutils/src/java/org/apache/commons/beanutils/MethodUtils.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- MethodUtils.java 4 Sep 2002 19:23:45 -0000 1.13
+++ MethodUtils.java 22 Sep 2002 21:45:35 -0000 1.14
@@ -72,6 +72,18 @@
/**
* <p> Utility reflection methods focussed on methods in general rather than
properties in particular. </p>
*
+ * <h3>Known Limitations</h3>
+ * <h4>Accessing Public Methods In A Default Access Superclass</h4>
+ * <p>There is an issue when invoking public methods contained in a default access
superclass.
+ * Reflection locates these methods fine and correctly assigns them as public.
+ * However, an <code>IllegalAccessException</code> is thrown if the method is
invoked.</p>
+ *
+ * <p><code>MethodUtils</code> contains a workaround for this situation.
+ * It will attempt to call <code>setAccessible</code> on this method.
+ * If this call succeeds, then the method can be invoked as normal.
+ * This call will only succeed when the application has sufficient security
privilages.
+ * If this call fails then a warning will be logged and the method may fail.</p>
+ *
* @author Craig R. McClanahan
* @author Ralph Schaer
* @author Chris Audley
@@ -541,6 +553,36 @@
// most of the time this works and it's much faster
try {
Method method = clazz.getMethod(methodName, parameterTypes);
+ if (log.isTraceEnabled()) {
+ log.trace("Found straight match: " + method);
+ log.trace("isPublic:" + Modifier.isPublic(method.getModifiers()));
+ }
+
+ try {
+ //
+ // XXX Default access superclass workaround
+ //
+ // When a public class has a default access superclass
+ // with public methods, these methods are accessible.
+ // Calling them from compiled code works fine.
+ //
+ // Unfortunately, using reflection to invoke these methods
+ // seems to (wrongly) to prevent access even when the method
+ // modifer is public.
+ //
+ // The following workaround solves the problem but will only
+ // work from sufficiently privilages code.
+ //
+ // Better workarounds would be greatfully accepted.
+ //
+ method.setAccessible(true);
+
+ } catch (SecurityException se) {
+ // log but continue just in case the method.invoke works anyway
+ log.warn(
+ "Cannot setAccessible on method. Therefore cannot use jvm access
bug workaround.",
+ se);
+ }
return method;
} catch (NoSuchMethodException e) { /* SWALLOW */ }
@@ -583,6 +625,19 @@
if (log.isTraceEnabled()) {
log.trace(method + " accessible version of "
+ methods[i]);
+ }
+ try {
+ //
+ // XXX Default access superclass workaround
+ // (See above for more details.)
+ //
+ method.setAccessible(true);
+
+ } catch (SecurityException se) {
+ // log but continue just in case the method.invoke
works anyway
+ log.warn(
+ "Cannot setAccessible on method. Therefore cannot
use jvm access bug workaround.",
+ se);
}
return method;
}
1.10 +18 -1
jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/MethodUtilsTestCase.java
Index: MethodUtilsTestCase.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/MethodUtilsTestCase.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- MethodUtilsTestCase.java 4 Sep 2002 19:23:45 -0000 1.9
+++ MethodUtilsTestCase.java 22 Sep 2002 21:45:35 -0000 1.10
@@ -63,6 +63,7 @@
import java.lang.reflect.Modifier;
import org.apache.commons.beanutils.priv.PrivateBeanFactory;
+import org.apache.commons.beanutils.priv.PublicSubBean;
import junit.framework.TestCase;
import junit.framework.Test;
@@ -565,5 +566,21 @@
}
-
+ public void testPublicSub() throws Exception {
+ // make sure that bean does what it should
+ PublicSubBean bean = new PublicSubBean();
+ assertEquals("Start value (foo)", bean.getFoo(), "This is foo");
+ assertEquals("Start value (bar)", bean.getBar(), "This is bar");
+ bean.setFoo("new foo");
+ bean.setBar("new bar");
+ assertEquals("Set value (foo)", bean.getFoo(), "new foo");
+ assertEquals("Set value (bar)", bean.getBar(), "new bar");
+
+ // see if we can access public methods in a default access superclass
+ // from a public access subclass instance
+ MethodUtils.invokeMethod(bean, "setFoo", "alpha");
+ assertEquals("Set value (foo:2)", bean.getFoo(), "alpha");
+ MethodUtils.invokeMethod(bean, "setBar", "beta");
+ assertEquals("Set value (bar:2)", bean.getFoo(), "alpha");
+ }
}
1.1
jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/priv/PackageBean.java
Index: PackageBean.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/priv/PackageBean.java,v
1.1 2002/09/22 21:45:35 rdonkin Exp $
* $Revision: 1.1 $
* $Date: 2002/09/22 21:45:35 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.beanutils.priv;
/**
* <p>This class is designed to test the default access jvm problem workaround.
* The issue is that public methods of a public subclass contained in a default
access
* superclass are returned by reflection but an IllegalAccessException is thrown
* when they are invoked.</p>
*
* <p>This is the default access superclass</p>
*
* @author Robert Burrell Donkin
* @version $Revision: 1.1 $ $Date: 2002/09/22 21:45:35 $
*/
class PackageBean {
// ----------------------------------------------------------- Constructors
/**
* Package private constructor - can only use factory method to create
* beans.
*/
PackageBean() {
super();
}
// ------------------------------------------------------------- Properties
/**
*/
private String bar = "This is bar";
public String getBar() {
return (this.bar);
}
public void setBar(String bar) {
this.bar = bar;
}
}
1.1
jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/priv/PublicSubBean.java
Index: PublicSubBean.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/beanutils/src/test/org/apache/commons/beanutils/priv/PublicSubBean.java,v
1.1 2002/09/22 21:45:35 rdonkin Exp $
* $Revision: 1.1 $
* $Date: 2002/09/22 21:45:35 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.beanutils.priv;
/**
* <p>This class is designed to test the default access jvm problem workaround.
* The issue is that public methods of a public subclass contained in a default
access
* superclass are returned by reflection but an IllegalAccessException is thrown
* when they are invoked.</p>
*
* <p>This is the default access superclass</p>
*
* @author Robert Burrell Donkin
* @version $Revision: 1.1 $ $Date: 2002/09/22 21:45:35 $
*/
public class PublicSubBean extends PackageBean {
// ----------------------------------------------------------- Constructors
/**
* Package private constructor - can only use factory method to create
* beans.
*/
public PublicSubBean() {
super();
}
// ------------------------------------------------------------- Properties
/**
* A directly implemented property.
*/
private String foo = "This is foo";
public String getFoo() {
return (this.foo);
}
public void setFoo(String foo) {
this.foo = foo;
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>