--- old/src/share/classes/java/lang/Class.java 2013-09-26 16:41:41.066118962 +0200 +++ new/src/share/classes/java/lang/Class.java 2013-09-26 16:41:40.886118953 +0200 @@ -1555,6 +1555,10 @@ *
If this {@code Class} object represents a primitive type or void, * then the returned array has length 0. * + *
Static methods declared in superinterfaces of the class or interface + * represented by this {@code Class} object are not considered members of + * the class or interface. + * *
The elements in the returned array are not sorted and are not in any * particular order. * @@ -1713,6 +1717,10 @@ *
If this {@code Class} object represents an array type, then this * method does not find the {@code clone()} method. * + *
Static methods declared in superinterfaces of the class or interface
+ * represented by this {@code Class} object are not considered members of
+ * the class or interface.
+ *
* @param name the name of the method
* @param parameterTypes the list of parameters
* @return the {@code Method} object that matches the specified
@@ -2711,6 +2719,14 @@
}
}
+ void addAllNonStatic(Method[] methods) {
+ for (Method candidate : methods) {
+ if (!Modifier.isStatic(candidate.getModifiers())) {
+ add(candidate);
+ }
+ }
+ }
+
int length() {
return length;
}
@@ -2781,7 +2797,7 @@
MethodArray inheritedMethods = new MethodArray();
Class>[] interfaces = getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
- inheritedMethods.addAll(interfaces[i].privateGetPublicMethods());
+ inheritedMethods.addAllNonStatic(interfaces[i].privateGetPublicMethods());
}
if (!isInterface()) {
Class> c = getSuperclass();
@@ -2910,9 +2926,9 @@
}
// Search superinterfaces' methods
Class>[] interfaces = getInterfaces();
- for (int i = 0; i < interfaces.length; i++) {
- Class> c = interfaces[i];
- if ((res = c.getMethod0(name, parameterTypes)) != null) {
+ for (Class> c : interfaces) {
+ if ((res = c.getMethod0(name, parameterTypes)) != null &&
+ !Modifier.isStatic(res.getModifiers())) {
return res;
}
}
--- old/test/java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java 2013-09-26 16:41:41.958119002 +0200
+++ new/test/java/lang/reflect/DefaultStaticTest/DefaultStaticInvokeTest.java 2013-09-26 16:41:41.762118993 +0200
@@ -44,30 +44,86 @@
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.fail;
import org.testng.annotations.Test;
import static helper.Mod.*;
import static helper.Declared.*;
import helper.Mod;
+
public class DefaultStaticInvokeTest {
+ // getMethods(): Make sure getMethods returns the expected methods.
@Test(dataProvider = "testCasesAll",
dataProviderClass = DefaultStaticTestData.class)
public void testGetMethods(String testTarget, Object param)
throws Exception {
- // test the methods retrieved by getMethods()
testMethods(ALL_METHODS, testTarget, param);
}
+
+ // getDeclaredMethods(): Make sure getDeclaredMethods returns the expected methods.
@Test(dataProvider = "testCasesAll",
dataProviderClass = DefaultStaticTestData.class)
public void testGetDeclaredMethods(String testTarget, Object param)
throws Exception {
- // test the methods retrieved by getDeclaredMethods()
testMethods(DECLARED_ONLY, testTarget, param);
}
+
+ // getMethod(): Make sure that getMethod finds all methods it should find.
+ @Test(dataProvider = "testCasesAll",
+ dataProviderClass = DefaultStaticTestData.class)
+ public void testGetMethod(String testTarget, Object param)
+ throws Exception {
+
+ Class> typeUnderTest = Class.forName(testTarget);
+
+ MethodDesc[] descs = typeUnderTest.getAnnotationsByType(MethodDesc.class);
+
+ for (MethodDesc desc : descs) {
+ assertTrue(isFoundByGetMethod(typeUnderTest,
+ desc.name(),
+ argTypes(param)));
+ }
+ }
+
+
+ // getMethod(): Make sure that getMethod does *not* find certain methods.
+ @Test(dataProvider = "testCasesAll",
+ dataProviderClass = DefaultStaticTestData.class)
+ public void testGetMethodSuperInterfaces(String testTarget, Object param)
+ throws Exception {
+
+ // Make sure static methods in superinterfaces are not found (unless the type under
+ // test declares a static method with the same signature).
+
+ Class> typeUnderTest = Class.forName(testTarget);
+
+ for (Class> interfaze : typeUnderTest.getInterfaces()) {
+
+ for (MethodDesc desc : interfaze.getAnnotationsByType(MethodDesc.class)) {
+
+ boolean isStatic = desc.mod() == STATIC;
+
+ boolean declaredInThisType = isMethodDeclared(typeUnderTest,
+ desc.name());
+
+ boolean expectedToBeFound = !isStatic || declaredInThisType;
+
+ if (expectedToBeFound)
+ continue; // already tested in testGetMethod()
+
+ assertFalse(isFoundByGetMethod(typeUnderTest,
+ desc.name(),
+ argTypes(param)));
+ }
+ }
+ }
+
+
+ // Method.invoke(): Make sure Method.invoke returns the expected value.
@Test(dataProvider = "testCasesAll",
dataProviderClass = DefaultStaticTestData.class)
public void testMethodInvoke(String testTarget, Object param)
@@ -78,11 +134,13 @@
// test the method retrieved by Class.getMethod(String, Object[])
for (MethodDesc toTest : expectedMethods) {
String name = toTest.name();
- Method m = getTestMethod(typeUnderTest, name, param);
+ Method m = typeUnderTest.getMethod(name, argTypes(param));
testThisMethod(toTest, m, typeUnderTest, param);
}
}
+
+ // MethodHandle.invoke(): Make sure MethodHandle.invoke returns the expected value.
@Test(dataProvider = "testCasesAll",
dataProviderClass = DefaultStaticTestData.class)
public void testMethodHandleInvoke(String testTarget, Object param)
@@ -116,6 +174,7 @@
}
+ // Lookup.findStatic / .findVirtual: Make sure IllegalAccessException is thrown as expected.
@Test(dataProvider = "testClasses",
dataProviderClass = DefaultStaticTestData.class)
public void testIAE(String testTarget, Object param)
@@ -128,7 +187,7 @@
String mName = toTest.name();
Mod mod = toTest.mod();
if (mod != STATIC && typeUnderTest.isInterface()) {
- return;
+ continue;
}
Exception caught = null;
try {
@@ -136,10 +195,12 @@
} catch (Exception e) {
caught = e;
}
- assertTrue(caught != null);
+ assertNotNull(caught);
assertEquals(caught.getClass(), IllegalAccessException.class);
}
}
+
+
private static final String[] OBJECT_METHOD_NAMES = {
"equals",
"hashCode",
@@ -192,15 +253,15 @@
myMethods.put(mName, m);
}
}
- assertEquals(expectedMethods.length, myMethods.size());
+
+ assertEquals(myMethods.size(), expectedMethods.length);
for (MethodDesc toTest : expectedMethods) {
String name = toTest.name();
- Method candidate = myMethods.get(name);
+ Method candidate = myMethods.remove(name);
assertNotNull(candidate);
- myMethods.remove(name);
testThisMethod(toTest, candidate, typeUnderTest, param);
@@ -210,6 +271,7 @@
assertTrue(myMethods.isEmpty());
}
+
private void testThisMethod(MethodDesc toTest, Method method,
Class> typeUnderTest, Object param) throws Exception {
// Test modifiers, and invoke
@@ -256,37 +318,52 @@
assertFalse(method.isDefault());
break;
default:
- assertFalse(true); //this should never happen
+ fail(); //this should never happen
break;
}
}
+
+ private boolean isMethodDeclared(Class> type, String name) {
+ MethodDesc[] methDescs = type.getAnnotationsByType(MethodDesc.class);
+ for (MethodDesc desc : methDescs) {
+ if (desc.declared() == YES && desc.name().equals(name))
+ return true;
+ }
+ return false;
+ }
+
+
+ private boolean isFoundByGetMethod(Class> c, String method, Class>... argTypes) {
+ try {
+ c.getMethod(method, argTypes);
+ return true;
+ } catch (NoSuchMethodException notFound) {
+ return false;
+ }
+ }
+
+
+ private Class>[] argTypes(Object param) {
+ return param == null ? new Class[0] : new Class[] { Object.class };
+ }
+
+
private Object tryInvoke(Method m, Class> receiverType, Object param)
throws Exception {
Object receiver = receiverType == null ? null : receiverType.newInstance();
- Object result = null;
- if (param == null) {
- result = m.invoke(receiver);
- } else {
- result = m.invoke(receiver, param);
- }
- return result;
+ Object[] args = param == null ? new Object[0] : new Object[] { param };
+ return m.invoke(receiver, args);
}
- private Method getTestMethod(Class clazz, String methodName, Object param)
- throws NoSuchMethodException {
- Class[] paramsType = (param != null)
- ? new Class[]{Object.class}
- : new Class[]{};
- return clazz.getMethod(methodName, paramsType);
- }
private MethodHandle getTestMH(Class clazz, String methodName, Object param)
throws Exception {
return getTestMH(clazz, methodName, param, false);
}
+
private MethodHandle getTestMH(Class clazz, String methodName,
Object param, boolean isNegativeTest)
throws Exception {
--- old/test/java/lang/reflect/DefaultStaticTest/DefaultStaticTestData.java 2013-09-26 16:41:42.702119038 +0200
+++ new/test/java/lang/reflect/DefaultStaticTest/DefaultStaticTestData.java 2013-09-26 16:41:42.506119025 +0200
@@ -172,7 +172,7 @@
@MethodDesc(name = "defaultMethod", retval = "TestIF8.TestClass8", mod = DEFAULT, declared = NO)
class TestClass8