undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8304585
* @run junit CallerSensitiveMethodInvoke
* @summary Test Method::invoke that wraps exception in InvocationTargetException properly
*/
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class CallerSensitiveMethodInvoke {
private int value = 10;
private void m() throws Exception {
throw new InvocationTargetException(new IllegalArgumentException("testing"));
}
/**
* Tests the Field::get method being invoked via Method::invoke which
* should throw InvocationTargetException thrown by Field::get.
*/
@Test
public void csMethodInvoke() throws ReflectiveOperationException {
Field f = CallerSensitiveMethodInvoke.class.getDeclaredField("value");
try {
// Field::get throws IAE
Method m = Field.class.getDeclaredMethod("get", Object.class);
m.invoke(f, new Object()); // illegal receiver type. IAE thrown
fail("should not reach here");
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (!(t instanceof IllegalArgumentException)) {
throw new RuntimeException("Unexpected cause of InvocationTargetException: " + t);
}
}
}
/**
* Tests the method being invoked throws InvocationTargetException which
* will be wrapped with another InvocationTargetException by Method::invoke.
*/
@Test
public void methodInvoke() throws ReflectiveOperationException {
try {
// m() throws InvocationTargetException which will be wrapped by Method::invoke
Method m = CallerSensitiveMethodInvoke.class.getDeclaredMethod("m");
m.invoke(new CallerSensitiveMethodInvoke());
fail("should not reach here");
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (!(t instanceof InvocationTargetException)) {
throw new RuntimeException("Unexpected cause of InvocationTargetException: " + t);
}
}
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4913433
* @summary Generic framework to test Method.equals.
*
* @clean A
* @compile Equals.java
* @run main Equals
*/
import java.lang.reflect.*;
class A {
public Object m() { return this; }
}
public class Equals extends A {
public Equals m() { return this; }
public static void main(String [] args) {
Equals e = new Equals();
e.returnType();
}
private void returnType() {
Class c = this.getClass();
Method [] ma = c.getMethods();
Method m0 = null, m1 = null;
for (int i = 0; i < ma.length; i++) {
if (ma[i].getName().equals("m")) {
if (m0 == null) {
m0 = ma[i];
continue;
} else {
m1 = ma[i];
break;
}
}
}
if (m0 == null || m1 == null)
throw new RuntimeException("Can't find bridge methods");
if (m0.equals(m1))
throw new RuntimeException("Return types not compared");
System.out.println("\"" + m0 + "\" and \"" + m1 + "\" are different");
}
}

View file

@ -0,0 +1,197 @@
/*
* Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 5033583 6316717 6470106 8004979 8161500 8162539 6304578
* @summary Check toGenericString() and toString() methods
*/
import java.lang.reflect.*;
import java.lang.annotation.*;
import java.util.*;
public class GenericStringTest {
public static void main(String argv[]) throws Exception {
int failures = 0;
for(Class<?> clazz: List.of(TestClass1.class, TestClass2.class,
Roebling.class, TestInterface1.class))
for(Method method: clazz.getDeclaredMethods()) {
ExpectedGenericString egs = method.getAnnotation(ExpectedGenericString.class);
if (egs != null) {
String actual = method.toGenericString();
System.out.println(actual);
if (method.isBridge()) {
failures += checkForFailure(egs.bridgeValue(), actual);
} else {
failures += checkForFailure(egs.value(), actual);
}
}
if (method.isAnnotationPresent(ExpectedString.class)) {
ExpectedString es = method.getAnnotation(ExpectedString.class);
String actual = method.toString();
failures += checkForFailure(es.value(), actual);
}
}
// Bridge Test; no "volatile" methods
for(Method method: Roebling.class.getDeclaredMethods()) {
String s1 = method.toGenericString();
String s2 = method.toString();
System.out.println("Generic: " + s1);
System.out.println("Regular: " + s2);
if (s1.indexOf("volatile") != -1 ||
s2.indexOf("volatile") != -1) {
failures++;
System.err.println("ERROR: Bad string; unexpected ``volatile''");
}
}
if (failures > 0) {
System.err.println("Test failed.");
throw new RuntimeException();
}
}
private static int checkForFailure(String expected, String actual) {
if (!expected.equals(actual)) {
System.err.printf("ERROR: Expected ''%s'';%ngot ''%s''.\n",
expected, actual);
return 1;
} else
return 0;
}
}
class TestClass1 {
@ExpectedGenericString(
"void TestClass1.method1(int,double)")
void method1(int x, double y) {}
@ExpectedGenericString(
"private static java.lang.String TestClass1.method2(int,int)")
private static String method2(int x, int param2) {return null;}
@ExpectedGenericString(
"static void TestClass1.method3() throws java.lang.RuntimeException")
static void method3() throws RuntimeException {return;}
@ExpectedGenericString(
"protected <S,T> S TestClass1.method4(S,T) throws java.lang.Exception")
protected <S, T> S method4(S s, T t) throws Exception {return null;}
@ExpectedGenericString(
"public static <T> T TestClass1.max(java.util.Collection<? extends T>,java.util.Comparator<? super T>)")
public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) {return null;}
}
class TestClass2<E, F extends Exception> {
@ExpectedGenericString(
"public <T> T TestClass2.method1(E,T)")
public <T> T method1(E e, T t) {return null;}
@ExpectedGenericString(
"public void TestClass2.method2() throws F")
@ExpectedString(
"public void TestClass2.method2() throws java.lang.Exception")
public void method2() throws F {return;}
@ExpectedGenericString(
"public E[] TestClass2.method3()")
public E[] method3() {return null;}
@ExpectedGenericString(
"public E[][] TestClass2.method4()")
public E[][] method4() {return null;}
@ExpectedGenericString(
"public java.util.List<E[]> TestClass2.method5()")
public List<E[]> method5() {return null;}
@ExpectedGenericString(
"public java.util.List<?> TestClass2.method6()")
public List<?> method6() {return null;}
@ExpectedGenericString(
"public java.util.List<?>[] TestClass2.method7()")
public List<?>[] method7() {return null;}
@ExpectedGenericString(
"public <K,V> java.util.Map<K, V> TestClass2.method8()")
public <K, V> Map<K, V> method8() {return null;}
@ExpectedGenericString(
"public <V extends java.lang.Number & java.lang.Runnable> java.util.Set<V> TestClass2.method9(V)")
public <V extends Number & Runnable> Set<V> method9(V v) {return null;}
}
class Roebling implements Comparable<Roebling> {
@ExpectedGenericString(
value="public int Roebling.compareTo(Roebling)",
bridgeValue="public int Roebling.compareTo(java.lang.Object)")
public int compareTo(Roebling r) {
throw new IllegalArgumentException();
}
// Not a transient method, (transient var-arg overlap)
@ExpectedGenericString(
"void Roebling.varArg(java.lang.Object...)")
@ExpectedString(
"void Roebling.varArg(java.lang.Object[])")
void varArg(Object ... arg) {}
}
interface TestInterface1 {
@ExpectedGenericString(
"public default void TestInterface1.foo()")
@ExpectedString(
"public default void TestInterface1.foo()")
public default void foo(){;}
@ExpectedString(
"public default java.lang.Object TestInterface1.bar()")
@ExpectedGenericString(
"public default <A> A TestInterface1.bar()")
default <A> A bar(){return null;}
@ExpectedString(
"public default double TestInterface1.quux()")
@ExpectedGenericString(
"public default double TestInterface1.quux()")
default double quux(){return 1.0;}
}
@Retention(RetentionPolicy.RUNTIME)
@interface ExpectedGenericString {
String value();
String bridgeValue() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@interface ExpectedString {
String value();
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4424393
@summary Failure to properly traverse superinterfaces
@author Kenneth Russell
*/
import java.lang.reflect.Method;
public class InheritedInterfaceMethods {
public static void main(String[] args) {
Method[] methods = InheritedInterfaceMethodsC.class.getMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().equals("a")) {
return;
}
}
throw new RuntimeException("TEST FAILED");
}
}
interface InheritedInterfaceMethodsA {
public void a();
}
interface InheritedInterfaceMethodsB extends InheritedInterfaceMethodsA {
public void b();
}
interface InheritedInterfaceMethodsC extends InheritedInterfaceMethodsB {
public void c();
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4471738
@summary Failure to properly traverse class hierarchy in Class.getMethod()
*/
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
public class InheritedMethods {
public static void main(String[] args) throws Exception { new InheritedMethods(); }
InheritedMethods() throws Exception {
Class c = Foo.class;
Method m = c.getMethod("removeAll", new Class[] { Collection.class });
if (m.getDeclaringClass() != java.util.List.class) {
throw new RuntimeException("TEST FAILED");
}
}
interface Foo extends List { }
}

View file

@ -0,0 +1,181 @@
/*
* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8009411
* @summary Test that a static method on an interface doesn't hide a default
* method with the same name and signature in a separate compilation
* scenario.
* @run main StaticInterfaceMethodInWayOfDefault
*/
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
public class StaticInterfaceMethodInWayOfDefault {
public interface A_v1 {
}
public interface A_v2 {
default void m() {
System.err.println("A.m() called");
}
}
public interface B extends A_v1 {
static void m() {
System.err.println("B.m() called");
}
}
public interface C_v1 extends B {
default void m() {
System.err.println("C.m() called");
}
}
public interface C_v2 extends B {
}
public static class TestTask implements Callable<String> {
@Override
public String call() {
try {
Method m = C_v1.class.getMethod("m", (Class<?>[])null);
return m.getDeclaringClass().getSimpleName();
} catch (NoSuchMethodException e) {
System.err.println("Couldn't find method");
return "ERROR";
}
}
}
public static void main(String[] args) throws Exception {
int errors = 0;
Callable<String> v1Task = new TestTask();
ClassLoader v2Loader = new V2ClassLoader(
StaticInterfaceMethodInWayOfDefault.class.getClassLoader());
Callable<String> v2Task = (Callable<String>) Class.forName(
TestTask.class.getName(),
true,
v2Loader).newInstance();
System.err.println("Running using _v1 classes:");
String res = v1Task.call();
if(!res.equals("C_v1")) {
System.err.println("Got wrong method, expecting C_v1, got: " + res);
errors++;
}
System.err.println("Running using _v2 classes:");
res = v2Task.call();
if(!res.equals("A_v1")) {
System.err.println("Got wrong method, expecting A_v1, got: " + res);
errors++;
}
if (errors != 0)
throw new RuntimeException("Errors found, check log for details");
}
/**
* A ClassLoader implementation that loads alternative implementations of
* classes. If class name ends with "_v1" it locates instead a class with
* name ending with "_v2" and loads that class instead.
*/
static class V2ClassLoader extends ClassLoader {
V2ClassLoader(ClassLoader parent) {
super(parent);
}
@Override
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
if (name.indexOf('.') < 0) { // root package is our class
synchronized (getClassLoadingLock(name)) {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
c = findClass(name);
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
else { // not our class
return super.loadClass(name, resolve);
}
}
@Override
protected Class<?> findClass(String name)
throws ClassNotFoundException {
// special class name -> replace it with alternative name
if (name.endsWith("_v1")) {
String altName = name.substring(0, name.length() - 3) + "_v2";
String altPath = altName.replace('.', '/').concat(".class");
try (InputStream is = getResourceAsStream(altPath)) {
if (is != null) {
byte[] bytes = is.readAllBytes();
// patch class bytes to contain original name
for (int i = 0; i < bytes.length - 2; i++) {
if (bytes[i] == '_' &&
bytes[i + 1] == 'v' &&
bytes[i + 2] == '2') {
bytes[i + 2] = '1';
}
}
return defineClass(name, bytes, 0, bytes.length);
}
else {
throw new ClassNotFoundException(name);
}
}
catch (IOException e) {
throw new ClassNotFoundException(name, e);
}
}
else { // not special class name -> just load the class
String path = name.replace('.', '/').concat(".class");
try (InputStream is = getResourceAsStream(path)) {
if (is != null) {
byte[] bytes = is.readAllBytes();
return defineClass(name, bytes, 0, bytes.length);
}
else {
throw new ClassNotFoundException(name);
}
}
catch (IOException e) {
throw new ClassNotFoundException(name, e);
}
}
}
}
}

View file

@ -0,0 +1,173 @@
/*
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8005042
* @summary Check behavior of Method.isDefault
*/
import java.lang.reflect.*;
import java.lang.annotation.*;
import java.util.*;
public class IsDefaultTest {
public static void main(String... argv) throws Exception {
int failures = 0;
int visitationCount = 0;
List<Class<?>> classList = new ArrayList<>();
classList.add(TestType1.class);
classList.add(TestType2.class);
classList.add(TestType3.class);
classList.add(TestType4.class);
classList.add(TestType2.nestedTestType2.class);
classList.add(TestType5.class);
classList.add(TestType5.nestedTestType5.class);
classList.add(TestType6.class);
classList.add(TestType6.nestedTestType6.class);
classList.add(TestType7.class);
for(Class<?> clazz: classList) {
for(Method method: clazz.getDeclaredMethods()) {
ExpectedIsDefault expectedIsDefault = method.getAnnotation(ExpectedIsDefault.class);
if (expectedIsDefault != null) {
visitationCount++;
boolean expected = expectedIsDefault.value();
boolean actual = method.isDefault();
if (actual != expected) {
failures++;
System.err.printf("ERROR: On %s expected isDefault of ''%s''; got ''%s''.\n",
method.toString(), expected, actual);
}
}
}
}
if (visitationCount == 0) {
System.err.println("Test failed because no methods checked.");
throw new RuntimeException();
}
if (failures > 0) {
System.err.println("Test failed.");
throw new RuntimeException();
}
}
}
interface TestType1 {
@ExpectedIsDefault(false)
void foo();
@ExpectedIsDefault(true)
default void bar() {}; // Default method
@ExpectedIsDefault(true)
default void bar(int i) {}; // Default method
@ExpectedIsDefault(true)
default void bar(String i) {}; // Default method
}
class TestType2 {
@ExpectedIsDefault(false)
void bar() {};
interface nestedTestType2 {
@ExpectedIsDefault(true)
default void nestedBar() {};
}
}
class TestType3 implements TestType1 {
@ExpectedIsDefault(false)
public void foo(){}
@ExpectedIsDefault(false)
@Override
public void bar() {};
@ExpectedIsDefault(false)
@Override
public void bar(int i) {};
}
@interface TestType4 {
@ExpectedIsDefault(false)
String value();
@ExpectedIsDefault(false)
String anotherValue() default "";
}
interface TestType5 {
@ExpectedIsDefault(false)
abstract void aFoo();
@ExpectedIsDefault(false)
static void sFoo() {};
@ExpectedIsDefault(true)
public default void pBar() {};
@ExpectedIsDefault(true)
public default String sBar() {return "";};
interface nestedTestType5{
@ExpectedIsDefault(false)
void nestedFoo();
@ExpectedIsDefault(true)
default void nestedBar() {};
}
}
class TestType6{
interface nestedTestType6 {
@ExpectedIsDefault(true)
default void nestedBar() {};
@ExpectedIsDefault(false)
void nestedFoo();
}
@ExpectedIsDefault(false)
void foo(nestedTestType6 n) {}
}
class TestType7 implements TestType6.nestedTestType6 {
@ExpectedIsDefault(false)
public void nestedFoo() {}
@ExpectedIsDefault(false)
@Override
public void nestedBar() {};
}
@Retention(RetentionPolicy.RUNTIME)
@interface ExpectedIsDefault {
boolean value();
}

View file

@ -0,0 +1,102 @@
/*
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8271820
* @run junit/othervm MethodArityLimit
* @summary Method exceeds the method handle arity limit (255).
*/
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class MethodArityLimit {
@Test
public void testArityLimit() throws Throwable {
Method m = this.getClass().getMethod("f", long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, long.class,
long.class, long.class, long.class, long.class, long.class, int.class);
long resultViaMethod = (long) m.invoke(null, 0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L,
8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L,
23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L, 32L, 33L, 34L, 35L, 36L,
37L, 38L, 39L, 40L, 41L, 42L, 43L, 44L, 45L, 46L, 47L, 48L, 49L, 50L,
51L, 52L, 53L, 54L, 55L, 56L, 57L, 58L, 59L, 60L, 61L, 62L, 63L, 64L,
65L, 66L, 67L, 68L, 69L, 70L, 71L, 72L, 73L, 74L, 75L, 76L, 77L, 78L,
79L, 80L, 81L, 82L, 83L, 84L, 85L, 86L, 87L, 88L, 89L, 90L, 91L, 92L,
93L, 94L, 95L, 96L, 97L, 98L, 99L, 100L, 101L, 102L, 103L, 104L, 105L,
106L, 107L, 108L, 109L, 110L, 111L, 112L, 113L, 114L, 115L, 116L, 117L,
118L, 119L, 120L, 121L, 122L, 123L, 124L, 125L, 126L, 127);
assertEquals(127, resultViaMethod);
var lookup = MethodHandles.lookup();
assertThrows(IllegalArgumentException.class, () -> lookup.unreflect(m));
}
public static long f(long a0, long a1, long a2, long a3, long a4, long a5,
long a6, long a7, long a8, long a9, long a10, long a11, long a12,
long a13, long a14, long a15, long a16, long a17, long a18, long a19,
long a20, long a21, long a22, long a23, long a24, long a25, long a26,
long a27, long a28, long a29, long a30, long a31, long a32, long a33,
long a34, long a35, long a36, long a37, long a38, long a39, long a40,
long a41, long a42, long a43, long a44, long a45, long a46, long a47,
long a48, long a49, long a50, long a51, long a52, long a53, long a54,
long a55, long a56, long a57, long a58, long a59, long a60, long a61,
long a62, long a63, long a64, long a65, long a66, long a67, long a68,
long a69, long a70, long a71, long a72, long a73, long a74, long a75,
long a76, long a77, long a78, long a79, long a80, long a81, long a82,
long a83, long a84, long a85, long a86, long a87, long a88, long a89,
long a90, long a91, long a92, long a93, long a94, long a95, long a96,
long a97, long a98, long a99, long a100, long a101, long a102, long a103,
long a104, long a105, long a106, long a107, long a108, long a109,
long a110, long a111, long a112, long a113, long a114, long a115,
long a116, long a117, long a118, long a119, long a120, long a121,
long a122, long a123, long a124, long a125, long a126, int a127) {
return a127;
}
}

View file

@ -0,0 +1,252 @@
/*
* Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8011590
* @summary Check modeling of default methods
*/
import java.util.Objects;
import java.lang.reflect.*;
import java.lang.annotation.*;
import static java.lang.reflect.Modifier.*;
public class DefaultMethodModeling {
public static void main(String... args) {
int failures = 0;
Class<?>[] classes = {SuperC.class, SuperCchild.class,
SuperI.class, SuperIchild.class,
SuperIwithDefault.class, SuperIwithDefaultChild.class,
Base.class, Combo1.class, Combo2.class,
SonSuperIwithDefault.class, DaughterSuperIwithDefault.class, GrandchildSuperIwithDefault.class, D.class,
B.class, C.class, B1.class, D1.class
};
for(Class<?> clazz : classes) {
System.err.println(clazz.toString());
for(Method m : clazz.getMethods()) {
if (m.getDeclaringClass() != java.lang.Object.class)
failures += testMethod(m);
}
}
if (failures > 0)
throw new RuntimeException();
}
private static int testMethod(Method m) {
ExpectedModel em = Objects.requireNonNull(m.getAnnotation(ExpectedModel.class));
boolean failed = false;
if (m.getModifiers() != em.modifiers()) {
failed = true;
System.err.printf("Unexpected modifiers %d; expected %d%n", m.getModifiers(), em.modifiers());
}
if (m.isDefault() != em.isDefault()) {
failed = true;
System.err.printf("Unexpected isDefualt %b; expected b%n", m.isDefault(), em.isDefault());
}
if (!m.getDeclaringClass().equals(em.declaringClass())) {
failed = true;
System.err.printf("Unexpected isDefualt %s; expected %s%n",
m.getDeclaringClass().toString(), em.declaringClass().toString());
}
return (!failed) ? 0 :1;
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface ExpectedModel {
boolean isDefault() default false;
int modifiers() default PUBLIC;
Class<?> declaringClass();
}
abstract class SuperC {
@ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=SuperC.class)
public abstract void foo();
@ExpectedModel(declaringClass=SuperC.class)
public void bar() {
;
}
}
class SuperCchild extends SuperC {
@ExpectedModel(declaringClass=SuperCchild.class)
@Override
public void foo() {;}
}
// -=-=-=-
interface SuperI {
@ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=SuperI.class)
void foo();
@ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=SuperI.class)
void bar();
}
class SuperIchild implements SuperI {
@ExpectedModel(declaringClass=SuperIchild.class)
public void foo() {;}
@ExpectedModel(declaringClass=SuperIchild.class)
public void bar() {;}
}
// -=-=-=-
interface SuperIwithDefault {
@ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=SuperIwithDefault.class)
void foo();
@ExpectedModel(isDefault=true, declaringClass=SuperIwithDefault.class)
default void bar() {
;
}
}
class SuperIwithDefaultChild implements SuperIwithDefault {
@ExpectedModel(declaringClass=SuperIwithDefaultChild.class)
@Override
public void foo() {;}
}
// -=-=-=-
abstract class Base {
@ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=Base.class)
public abstract void baz();
@ExpectedModel(declaringClass=Base.class)
public void quux() {;}
}
abstract class Combo1 extends Base implements SuperI {
@ExpectedModel(declaringClass=Combo1.class)
public void wombat() {}
}
abstract class Combo2 extends Base implements SuperIwithDefault {
@ExpectedModel(declaringClass=Combo2.class)
public void wombat() {}
}
// -=-=-=-
interface SonSuperIwithDefault extends SuperIwithDefault {
@ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=SonSuperIwithDefault.class)
void baz();
@ExpectedModel(isDefault=true, declaringClass=SonSuperIwithDefault.class)
default void bazD() {;}
}
interface DaughterSuperIwithDefault extends SuperIwithDefault {
@ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=DaughterSuperIwithDefault.class)
void quux();
@ExpectedModel(isDefault=true, declaringClass=DaughterSuperIwithDefault.class)
default void quuxD() {;}
}
interface GrandchildSuperIwithDefault extends SonSuperIwithDefault, DaughterSuperIwithDefault {
@ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=GrandchildSuperIwithDefault.class)
void wombat();
@ExpectedModel(isDefault=true, declaringClass=GrandchildSuperIwithDefault.class)
default void wombatD() {;}
}
class D implements GrandchildSuperIwithDefault {
@ExpectedModel(declaringClass=D.class)
public void wombat(){}
@ExpectedModel(declaringClass=D.class)
public void baz(){}
@ExpectedModel(declaringClass=D.class)
public void foo(){}
@ExpectedModel(declaringClass=D.class)
public void quux(){}
}
class D1 implements SonSuperIwithDefault, DaughterSuperIwithDefault {
@ExpectedModel(declaringClass=D1.class)
public void foo(){}
@ExpectedModel(declaringClass=D1.class)
public void baz(){}
@ExpectedModel(declaringClass=D1.class)
public void quux(){}
}
// -=-=-=-
// What does re-abstraction look like?
class A implements SuperIwithDefault {
@ExpectedModel(declaringClass=A.class)
@Override
public void foo(){;}
}
abstract class B extends A {
@ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=B.class)
@Override
public abstract void bar();
}
class C extends B implements SuperIwithDefault {
@ExpectedModel(declaringClass=C.class)
public void bar(){}
}
abstract class A1 implements SonSuperIwithDefault {
@ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=A1.class)
public abstract void baz();
@ExpectedModel(modifiers=PUBLIC|ABSTRACT, declaringClass=A1.class)
public abstract void foo();
}
class B1 extends A1 {
@ExpectedModel(declaringClass=B1.class)
@Override
public void foo(){;}
@ExpectedModel(declaringClass=B1.class)
@Override
public void baz(){}
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4428861
@summary Method.invoke() should wrap all Throwables in InvocationTargetException
@author Kenneth Russell
*/
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
public class ErrorInInvoke {
public static void run() {
throw new AbstractMethodError("Not really, just testing");
}
public static void main(String[] args) {
Method m = null;
try {
m = ErrorInInvoke.class.getMethod("run", new Class[] {});
} catch (Throwable t) {
throw new RuntimeException("Test failed (getMethod() failed");
}
try {
m.invoke(null, null);
} catch (AbstractMethodError e) {
throw new RuntimeException("Test failed (AbstractMethodError passed through)");
} catch (InvocationTargetException e) {
Throwable t = e.getTargetException();
if (!(t instanceof AbstractMethodError)) {
throw new RuntimeException("Test failed (InvocationTargetException didn't wrap AbstractMethodError)");
}
} catch (Throwable t) {
throw new RuntimeException("Test failed (Unexpected exception)");
}
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4109289
@summary Turning off access checks now enables illegal reflection.
@author Anand Palaniswamy
*/
import java.lang.reflect.Method;
/**
* Try to call a private method with Method.invoke(). If that doesn't
* throw a IllegalAccessException, then access checks are disabled,
* which is a bad idea.
*/
public class IllegalAccessInInvoke {
public static void main(String[] argv) {
Class[] argTypes = new Class[0];
Object[] args = new Object[0];
Method pm = null;
try {
pm = Foo.class.getDeclaredMethod("privateMethod", argTypes);
} catch (NoSuchMethodException nsme) {
throw new
RuntimeException("Bizzare: privateMethod *must* be there");
}
boolean ethrown = false;
try {
pm.invoke(new Foo(), args);
} catch (IllegalAccessException iae) {
ethrown = true;
} catch (Exception e) {
throw new RuntimeException("Unexpected " + e.toString());
}
if (!ethrown) {
throw new
RuntimeException("Reflection access checks are disabled");
}
}
}
class Foo {
private void privateMethod() {
}
}

View file

@ -0,0 +1,130 @@
/*
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 5043030
* @summary Verify that the method java.lang.reflect.Method.invoke(Object, Object...)
* makes use of the same caching mechanism as used for autoboxing
* when wrapping returned values of the primitive types.
* @author Andrej Golovnin
* @run main/othervm TestMethodReflectValueOf
*/
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestMethodReflectValueOf {
public static void main(String[] args) {
// When the inflation is disabled we compare values using "=="
// as the returned values of the primitive types should be cached
// by the same mechanism as used for autoboxing. When the inflation
// is enabled we use "equals()"-method to compare values as the native
// code still creates new instances to wrap values of the primitive
// types.
boolean checkIdentity = Boolean.getBoolean("sun.reflect.noInflation");
// Boolean#valueOf test
testMethod(Boolean.TYPE, Boolean.FALSE, checkIdentity);
testMethod(Boolean.TYPE, Boolean.TRUE, checkIdentity);
// Byte#valueOf test
for (int b = Byte.MIN_VALUE; b < (Byte.MAX_VALUE + 1); b++) {
testMethod(Byte.TYPE, Byte.valueOf((byte) b), checkIdentity);
}
// Character#valueOf test
for (char c = '\u0000'; c <= '\u007F'; c++) {
testMethod(Character.TYPE, Character.valueOf(c), checkIdentity);
}
// Integer#valueOf test
for (int i = -128; i <= 127; i++) {
testMethod(Integer.TYPE, Integer.valueOf(i), checkIdentity);
}
// Long#valueOf test
for (long l = -128L; l <= 127L; l++) {
testMethod(Long.TYPE, Long.valueOf(l), checkIdentity);
}
// Short#valueOf test
for (short s = -128; s <= 127; s++) {
testMethod(Short.TYPE, Short.valueOf(s), checkIdentity);
}
}
public static void testMethod(Class<?> primType, Object wrappedValue,
boolean checkIdentity)
{
String methodName = primType.getName() + "Method";
try {
Method method = TestMethodReflectValueOf.class.getMethod(methodName, primType);
Object result = method.invoke(new TestMethodReflectValueOf(), wrappedValue);
if (checkIdentity) {
if (result != wrappedValue) {
throw new RuntimeException("The value " + wrappedValue
+ " is not cached for the type " + primType);
}
} else {
if (!result.equals(wrappedValue)) {
throw new RuntimeException("The result value " + result
+ " is not equal to the expected value "
+ wrappedValue + " for the type " + primType);
}
}
} catch ( NoSuchMethodException | SecurityException
| IllegalAccessException | IllegalArgumentException
| InvocationTargetException e)
{
throw new RuntimeException(e);
}
}
public int intMethod(int value) {
return value;
}
public long longMethod(long value) {
return value;
}
public short shortMethod(short value) {
return value;
}
public byte byteMethod(byte value) {
return value;
}
public char charMethod(char value) {
return value;
}
public boolean booleanMethod(boolean value) {
return value;
}
}

View file

@ -0,0 +1,117 @@
/*
* Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8026213
* @summary Reflection support for private methods in interfaces
* @author Robert Field
* @run main TestPrivateInterfaceMethodReflect
*/
import java.lang.classfile.ClassFile;
import java.lang.constant.ClassDesc;
import java.lang.constant.MethodTypeDesc;
import java.lang.reflect.*;
import static java.lang.classfile.ClassFile.ACC_PRIVATE;
import static java.lang.classfile.ClassFile.ACC_PUBLIC;
import static java.lang.constant.ConstantDescs.CD_Object;
import static java.lang.constant.ConstantDescs.CD_int;
import static java.lang.constant.ConstantDescs.INIT_NAME;
import static java.lang.constant.ConstantDescs.MTD_void;
public class TestPrivateInterfaceMethodReflect {
static final String INTERFACE_NAME = "PrivateInterfaceMethodReflectTest_Interface";
static final String CLASS_NAME = "PrivateInterfaceMethodReflectTest_Class";
static final int EXPECTED = 1234;
static class TestClassLoader extends ClassLoader {
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
byte[] b;
try {
b = loadClassData(name);
} catch (Throwable th) {
// th.printStackTrace();
throw new ClassNotFoundException("Loading error", th);
}
return defineClass(name, b, 0, b.length);
}
private byte[] loadClassData(String name) {
return switch (name) {
case INTERFACE_NAME -> ClassFile.of().build(ClassDesc.ofInternalName(INTERFACE_NAME), clb -> {
clb.withFlags(AccessFlag.ABSTRACT, AccessFlag.INTERFACE, AccessFlag.PUBLIC);
clb.withSuperclass(CD_Object);
clb.withMethodBody("privInstance", MethodTypeDesc.of(CD_int), ACC_PRIVATE, cob -> {
cob.loadConstant(EXPECTED);
cob.ireturn();
});
});
case CLASS_NAME -> ClassFile.of().build(ClassDesc.of(CLASS_NAME), clb -> {
clb.withFlags(AccessFlag.PUBLIC);
clb.withSuperclass(CD_Object);
clb.withInterfaceSymbols(ClassDesc.ofInternalName(INTERFACE_NAME));
clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cob -> {
cob.aload(0);
cob.invokespecial(CD_Object, INIT_NAME, MTD_void);
cob.return_();
});
});
default -> throw new IllegalArgumentException();
};
}
}
public static void main(String[] args) throws Exception {
TestClassLoader tcl = new TestClassLoader();
Class<?> itf = tcl.loadClass(INTERFACE_NAME);
Class<?> k = tcl.loadClass(CLASS_NAME);
Object inst = k.getDeclaredConstructor().newInstance();
Method[] meths = itf.getDeclaredMethods();
if (meths.length != 1) {
throw new Exception("Expected one method in " + INTERFACE_NAME + " instead " + meths.length);
}
Method m = meths[0];
int mod = m.getModifiers();
if ((mod & Modifier.PRIVATE) == 0) {
throw new Exception("Expected " + m + " to be private");
}
if ((mod & Modifier.STATIC) != 0) {
throw new Exception("Expected " + m + " to be instance method");
}
m.setAccessible(true);
for (int i = 1; i < 200; i++) {
if (!m.invoke(inst).equals(EXPECTED)) {
throw new Exception("Expected " + EXPECTED + " from " + m);
}
}
System.out.println("Passed.");
}
}