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,77 @@
/*
* 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 5097856
* @summary Computing hashCode of objects modeling generics shouldn't blow stack
*/
import java.util.*;
import java.lang.reflect.*;
public class HashCodeTest {
// Mutually recursive interface types
interface Edge<N extends Node<? extends Edge<N>>> {
void setEndNode(N n);
}
interface Node<E extends Edge<? extends Node<E>>> {
E getOutEdge();
}
public static void main(String argv[]) {
List<Class<?>> classes = new ArrayList<Class<?>>();
Set<TypeVariable> typeVariables = new HashSet<TypeVariable>();
classes.add(java.lang.Class.class);// Simple case
classes.add(java.util.Map.class);
classes.add(java.lang.Enum.class); // Contains f-bound
classes.add(Edge.class);
classes.add(Node.class);
for(Class<?> clazz: classes) {
System.out.println(clazz);
for (TypeVariable<?> tv : clazz.getTypeParameters()) {
int hc = tv.hashCode();
typeVariables.add(tv);
System.out.printf("\t%s 0x%x (%d)%n", tv.getName(), hc, hc);
}
}
// Loop over classes again, making sure all type variables are
// already present
int count = 0;
for(Class<?> clazz: classes) {
for (TypeVariable<?> tv : clazz.getTypeParameters()) {
if (!typeVariables.remove(tv))
throw new RuntimeException("Type variable " + tv + " not found.");
}
}
if (typeVariables.size() != 0 )
throw new RuntimeException("Unexpected number of type variables.");
}
}

View file

@ -0,0 +1,224 @@
/*
* Copyright (c) 2024, 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 6832374 7052898 8350704
* @summary Test behaviors with malformed signature strings in Signature attribute.
* @library /test/lib
* @run junit MalformedSignatureTest
*/
import java.lang.classfile.*;
import java.lang.classfile.attribute.RecordAttribute;
import java.lang.classfile.attribute.RecordComponentInfo;
import java.lang.classfile.attribute.SignatureAttribute;
import java.lang.constant.ClassDesc;
import java.lang.reflect.GenericSignatureFormatError;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;
import jdk.test.lib.ByteCodeLoader;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static java.lang.constant.ConstantDescs.MTD_void;
import static org.junit.jupiter.api.Assertions.*;
class MalformedSignatureTest {
private static final String BASIC_BAD_SIGNATURE_TEXT = "i_aM_NoT_A_Signature";
static Class<?> sampleClass, sampleRecord;
@BeforeAll
static void setup() throws Exception {
var compiledDir = Path.of(System.getProperty("test.classes"));
var cf = ClassFile.of();
// Transform that installs malformed signature strings to classes,
// fields, methods, and record components.
var badSignatureTransform = new ClassTransform() {
private SignatureAttribute badSignature;
@Override
public void atStart(ClassBuilder builder) {
badSignature = SignatureAttribute.of(builder.constantPool().utf8Entry(BASIC_BAD_SIGNATURE_TEXT));
}
@Override
public void accept(ClassBuilder builder, ClassElement element) {
switch (element) {
case SignatureAttribute _ -> {} // dropping
case FieldModel f -> builder
.transformField(f, FieldTransform.dropping(SignatureAttribute.class::isInstance)
.andThen(FieldTransform.endHandler(fb -> fb.with(badSignature))));
case MethodModel m -> builder
.transformMethod(m, MethodTransform.dropping(SignatureAttribute.class::isInstance)
.andThen(MethodTransform.endHandler(fb -> fb.with(badSignature))));
case RecordAttribute rec -> builder.with(RecordAttribute.of(rec.components().stream().map(comp ->
RecordComponentInfo.of(comp.name(), comp.descriptor(), Stream.concat(
Stream.of(badSignature), comp.attributes().stream()
.filter(Predicate.not(SignatureAttribute.class::isInstance)))
.toList()))
.toList()));
default -> builder.with(element);
}
}
@Override
public void atEnd(ClassBuilder builder) {
builder.with(badSignature);
}
};
var plainBytes = cf.transformClass(cf.parse(compiledDir.resolve("SampleClass.class")), badSignatureTransform);
sampleClass = ByteCodeLoader.load("SampleClass", plainBytes);
var recordBytes = cf.transformClass(cf.parse(compiledDir.resolve("SampleRecord.class")), badSignatureTransform);
sampleRecord = ByteCodeLoader.load("SampleRecord", recordBytes);
}
/**
* Ensures the reflective generic inspection of a malformed Class throws
* GenericSignatureFormatError while the non-generic inspection is fine.
*/
@Test
void testBasicClass() {
assertEquals(ArrayList.class, sampleClass.getSuperclass());
assertArrayEquals(new Class<?>[] {Predicate.class}, sampleClass.getInterfaces());
var ex = assertThrows(GenericSignatureFormatError.class, sampleClass::getGenericSuperclass);
assertTrue(ex.getMessage().contains(BASIC_BAD_SIGNATURE_TEXT));
ex = assertThrows(GenericSignatureFormatError.class, sampleClass::getGenericInterfaces);
assertTrue(ex.getMessage().contains(BASIC_BAD_SIGNATURE_TEXT));
}
/**
* Ensures the reflective generic inspection of a malformed Field throws
* GenericSignatureFormatError while the non-generic inspection is fine.
*/
@Test
void testBasicField() throws ReflectiveOperationException {
var field = sampleClass.getDeclaredField("field");
assertEquals(Optional.class, field.getType());
var ex = assertThrows(GenericSignatureFormatError.class, field::getGenericType);
assertTrue(ex.getMessage().contains(BASIC_BAD_SIGNATURE_TEXT));
}
/**
* Ensures the reflective generic inspection of a malformed Constructor throws
* GenericSignatureFormatError while the non-generic inspection is fine.
*/
@Test
void testBasicConstructor() throws ReflectiveOperationException {
var constructor = sampleClass.getDeclaredConstructors()[0];
assertArrayEquals(new Class<?>[] {Optional.class}, constructor.getParameterTypes());
assertArrayEquals(new Class<?>[] {RuntimeException.class}, constructor.getExceptionTypes());
var ex = assertThrows(GenericSignatureFormatError.class, constructor::getGenericParameterTypes);
assertTrue(ex.getMessage().contains(BASIC_BAD_SIGNATURE_TEXT));
ex = assertThrows(GenericSignatureFormatError.class, constructor::getGenericExceptionTypes);
assertTrue(ex.getMessage().contains(BASIC_BAD_SIGNATURE_TEXT));
}
/**
* Ensures the reflective generic inspection of a malformed Method throws
* GenericSignatureFormatError while the non-generic inspection is fine.
*/
@Test
void testBasicMethod() throws ReflectiveOperationException {
var method = sampleClass.getDeclaredMethods()[0];
assertEquals(Optional.class, method.getReturnType());
assertArrayEquals(new Class<?>[] {Optional.class}, method.getParameterTypes());
assertArrayEquals(new Class<?>[] {RuntimeException.class}, method.getExceptionTypes());
var ex = assertThrows(GenericSignatureFormatError.class, method::getGenericReturnType);
assertTrue(ex.getMessage().contains(BASIC_BAD_SIGNATURE_TEXT));
ex = assertThrows(GenericSignatureFormatError.class, method::getGenericParameterTypes);
assertTrue(ex.getMessage().contains(BASIC_BAD_SIGNATURE_TEXT));
ex = assertThrows(GenericSignatureFormatError.class, method::getGenericExceptionTypes);
assertTrue(ex.getMessage().contains(BASIC_BAD_SIGNATURE_TEXT));
}
/**
* Ensures the reflective generic inspection of a malformed RecordComponent throws
* GenericSignatureFormatError while the non-generic inspection is fine.
*/
@Test
void testBasicRecordComponent() {
var rcs = sampleRecord.getRecordComponents();
assertNotNull(rcs);
assertEquals(1, rcs.length);
var rc = rcs[0];
assertNotNull(rc);
assertEquals(Optional.class, rc.getType());
assertEquals(BASIC_BAD_SIGNATURE_TEXT, rc.getGenericSignature());
var ex = assertThrows(GenericSignatureFormatError.class, rc::getGenericType);
assertTrue(ex.getMessage().contains(BASIC_BAD_SIGNATURE_TEXT));
}
static String[] badMethodSignatures() {
return new String[] {
// Missing ":" after first type bound
"<T:Lfoo/tools/nsc/symtab/Names;Lfoo/tools/nsc/symtab/Symbols;",
// Arrays improperly indicated for exception information
"<E:Ljava/lang/Exception;>(TE;[Ljava/lang/RuntimeException;)V^[TE;",
};
}
/**
* Ensures that particular strings are invalid as method signature strings.
*/
@MethodSource("badMethodSignatures")
@ParameterizedTest
void testSignatureForMethod(String badSig) throws Throwable {
var className = "BadSignature";
var bytes = ClassFile.of().build(ClassDesc.of(className), clb ->
clb.withMethod("test", MTD_void, 0, mb -> mb
.withCode(CodeBuilder::return_)
.with(SignatureAttribute.of(clb.constantPool().utf8Entry(badSig)))));
var cl = ByteCodeLoader.load(className, bytes);
var method = cl.getDeclaredMethod("test");
var ex = assertThrows(GenericSignatureFormatError.class, method::getGenericParameterTypes);
//assertTrue(ex.getMessage().contains(badSig), "Missing bad signature in error message");
}
}
// Sample classes shared with TypeNotPresentInSignatureTest
abstract class SampleClass extends ArrayList<RuntimeException> implements Predicate<RuntimeException> { // class
Optional<RuntimeException> field; // field
<T extends RuntimeException> SampleClass(Optional<RuntimeException> param) throws T {
} // constructor
<T extends RuntimeException> Optional<RuntimeException> method(Optional<RuntimeException> param) throws T {
return null;
} // method
}
record SampleRecord(Optional<RuntimeException> component) {
}

View file

@ -0,0 +1,132 @@
/*
* 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 5003916 6704655 6873951 6476261 8004928
* @summary Testing parsing of signatures attributes of nested classes
*/
import java.lang.reflect.*;
import java.lang.annotation.*;
import java.util.*;
import static java.util.Arrays.*;
@Classes({"java.util.concurrent.FutureTask",
"java.util.concurrent.ConcurrentHashMap$EntryIterator",
"java.util.concurrent.ConcurrentHashMap$KeyIterator",
"java.util.concurrent.ConcurrentHashMap$ValueIterator",
"java.util.AbstractList$ListItr",
"java.util.EnumMap$EntryIterator",
"java.util.EnumMap$KeyIterator",
"java.util.EnumMap$ValueIterator",
"java.util.IdentityHashMap$EntryIterator",
"java.util.IdentityHashMap$KeyIterator",
"java.util.IdentityHashMap$ValueIterator",
"java.util.WeakHashMap$EntryIterator",
"java.util.WeakHashMap$KeyIterator",
"java.util.WeakHashMap$ValueIterator",
"java.util.HashMap$EntryIterator",
"java.util.HashMap$KeyIterator",
"java.util.HashMap$ValueIterator",
"java.util.LinkedHashMap$LinkedEntryIterator",
"java.util.LinkedHashMap$LinkedKeyIterator",
"java.util.LinkedHashMap$LinkedValueIterator"})
public class Probe {
public static void main (String... args) throws Throwable {
Classes classesAnnotation = (Probe.class).getAnnotation(Classes.class);
List<String> names = new ArrayList<>(asList(classesAnnotation.value()));
int errs = 0;
for(String name: names) {
System.out.println("\nCLASS " + name);
Class c = Class.forName(name, false, null);
errs += probe(c);
System.out.println(errs == 0 ? " ok" : " ERRORS:" + errs);
}
if (errs > 0 )
throw new RuntimeException("Errors during probing.");
}
static int probe (Class c) {
int errs = 0;
try {
c.getTypeParameters();
c.getGenericSuperclass();
c.getGenericInterfaces();
} catch (Throwable t) {
errs++;
System.err.println(t);
}
Field[] fields = c.getDeclaredFields();
if (fields != null)
for(Field field: fields) {
try {
field.getGenericType();
} catch (Throwable t) {
errs++;
System.err.println("FIELD " + field);
System.err.println(t);
}
}
Method[] methods = c.getDeclaredMethods();
if (methods != null)
for(Method method: methods) {
try {
method.getTypeParameters();
method.getGenericReturnType();
method.getGenericParameterTypes();
method.getGenericExceptionTypes();
} catch (Throwable t) {
errs++;
System.err.println("METHOD " + method);
System.err.println(t);
}
}
Constructor[] ctors = c.getDeclaredConstructors();
if (ctors != null)
for(Constructor ctor: ctors) {
try {
ctor.getTypeParameters();
ctor.getGenericParameterTypes();
ctor.getGenericExceptionTypes();
} catch (Throwable t) {
errs++;
System.err.println("CONSTRUCTOR " + ctor);
System.err.println(t);
}
}
return errs;
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface Classes {
String [] value(); // list of classes to probe
}

View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 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 8372258
* @summary Test if a copy of the internal state is provided
* @run junit ProtectInnerStateOfTypeVariableImplTest
*/
import org.junit.jupiter.api.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.TypeVariable;
import static org.junit.jupiter.api.Assertions.*;
final class ProtectInnerStateOfTypeVariableImplTest {
static final class Foo {
public <X> Foo() {
}
<X> X x() {
return null;
}
}
@Test
void testMethod() throws NoSuchMethodException {
Method method = Foo.class.getDeclaredMethod("x");
TypeVariable<Method> tv = method.getTypeParameters()[0];
Method gd = tv.getGenericDeclaration();
Method gd2 = tv.getGenericDeclaration();
assertNotSame(gd, gd2);
}
@Test
void testConstructor() throws NoSuchMethodException {
Constructor<?> ctor = Foo.class.getConstructor();
TypeVariable<? extends Constructor<?>> tv = ctor.getTypeParameters()[0];
Constructor<?> gd = tv.getGenericDeclaration();
Constructor<?> gd2 = tv.getGenericDeclaration();
assertNotSame(gd, gd2);
}
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2006, 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 6476261
* @summary More testing of parsing of signatures attributes of nested classes
*/
import java.lang.reflect.*;
public class SignatureTest<T> {
class Inner1 {
class Inner11 {
}
}
public void f(SignatureTest<String>.Inner1.Inner11 x) {}
public void g(SignatureTest<String>.Inner1 x) {}
public static void main(String[] args) throws Exception {
Class clazz = SignatureTest.class;
for (Method m : clazz.getDeclaredMethods()) {
System.out.println();
System.out.println(m.toString());
System.out.println(m.toGenericString());
System.out.println(m.getGenericParameterTypes());
}
}
}

View file

@ -0,0 +1,93 @@
/*
* 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 5015676 4987888 4997464
* @summary Testing upper bounds and availability of toString methods
*/
import java.lang.reflect.*;
import java.util.List;
import java.util.Collection;
class A<T> {
class B<U> {}
}
class Test<T> {
static class Inner1<U> {
void bar(U[] array1) { return;}
}
class Inner2<V> {
List<?> foo2(List<? extends V> t) {
return null;
}
}
static <S extends Object & Comparable<? super S> > S max(Collection<? extends S> coll) {
return null;
}
List<? extends T> foo(List<? super T> t) {
return null;
}
}
public class StringsAndBounds {
public void f(A<String>.B<Integer> x) {
}
public <T> void g(T a) {return ;}
static void scanner(Class clazz) {
System.out.println("\n\nScanning " + clazz.getName());
for(Class c: clazz.getDeclaredClasses()) {
scanner(c);
}
for(Method m: clazz.getDeclaredMethods()) {
System.out.println("\nMethod:\t" + m.toString()); // Need toGenericString?
System.out.println("\tReturn Type: " + m.getGenericReturnType().toString() );
for(Type p: m.getGenericParameterTypes()) {
if (p instanceof WildcardType) { // Check upper bounds
Type[] upperBounds = ((WildcardType)p).getUpperBounds();
if (upperBounds.length < 1 ||
upperBounds[0] == null)
throw new RuntimeException("Malformed upper bounds: " + p);
}
System.out.println("\tParameter: " + p.toString());
}
}
}
public static void main(String[] argv) throws Exception {
scanner(StringsAndBounds.class);
scanner(A.B.class);
scanner(Test.class);
}
}

View file

@ -0,0 +1,340 @@
/*
* 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 4891872
* @summary Some tests for the generic core reflection api.
* @author Gilad Bracha
* @compile TestC1.java
* @run main/othervm -ea TestC1
*/
import java.lang.reflect.*;
abstract class C1<T> {
public T ft;
public C1<T> fc1t;
public C1 fc1;
public C1(T t) {}
public abstract C1<T> mc1t(T t, C1<T> c1t, C1 c1);
public abstract C1 mc1();
public abstract T mt(T t);
}
public class TestC1 {
static Class<C1> cls = C1.class;
static {
TestC1.class.getClassLoader().setDefaultAssertionStatus(true);
}
public static void main(String[] args) throws Throwable {
testSuperclass();
testSuperInterfaces();
testTypeParameters();
testMethods();
testConstructor();
testFields();
}
static void testSuperclass() {
System.out.println("testing superclass");
Type sc = cls.getGenericSuperclass();
assert
(sc == Object.class) :
"The generic superclass of C1 should be Object";
}
static void testSuperInterfaces() {
System.out.println("testing superinterfaces");
Type[] sis = cls.getGenericInterfaces();
assert
(sis.length == 0) :
"C1 should have no generic superinterfaces";
}
static void testTypeParameters() {
System.out.println("testing type parameters");
TypeVariable[] tvs = cls.getTypeParameters();
assert
tvs.length == 1 :
"C1 should have one type parameter";
TypeVariable tv = tvs[0];
Type[] bs = tv.getBounds();
assert
bs.length == 1 :
"T should have one bound";
assert
bs[0] == Object.class :
"The default bound of a type variable should be Object";
}
static void testMethods() throws NoSuchMethodException {
System.out.println("testing methods");
Class[] params1 = new Class[3];
params1[0] = Object.class;
params1[1] = cls;
params1[2] = cls;
Class[] params3 = new Class[1];
params3[0] = Object.class;
Method mc1t = cls.getMethod("mc1t", params1);
Method mc1 = cls.getMethod("mc1", new Class[0]);
Method mt = cls.getMethod("mt", params3);
Type rt_mc1t = mc1t.getGenericReturnType();
Type rt_mc1 = mc1.getGenericReturnType();
Type rt_mt = mt.getGenericReturnType();
Type[] pt_mc1t = mc1t.getGenericParameterTypes();
assert
pt_mc1t.length == 3 :
"C1.mc1t has three parameters";
Type p1_mc1t = pt_mc1t[0];
assert p1_mc1t != null;
assert
p1_mc1t instanceof TypeVariable :
"Generic type of the 1st parameter of mc1t(T) is a type variable";
TypeVariable tv = (TypeVariable) p1_mc1t;
assert
tv.getName().equals("T") :
"Name of 1st type parameter of mc1t is T, not " + tv.getName();
Type[] bs = tv.getBounds();
assert
bs.length == 1 :
"T should have one bound (mc1t)";
assert
bs[0] == Object.class :
"The bound of T should be Object (mc1t)";
Type p2_mc1t = pt_mc1t[1];
assert
p2_mc1t instanceof ParameterizedType :
"The type of parameter 2 of mc1t is a parameterized type";
ParameterizedType pt = (ParameterizedType) p2_mc1t;
assert
pt.getRawType() == cls :
"Type of parameter 2 of mc1t is instantiation of C1";
assert
pt.getOwnerType() == null :
"Type of parameter 2 of mc1t is has null owner";
Type[] tas = pt.getActualTypeArguments();
assert
tas.length == 1 :
"The type of parameter 2 of mc1t has one type argument";
Type ta = tas[0];
assert
ta instanceof TypeVariable :
"The actual type arg of C1<T> is a type variable (mc1t)";
tv = (TypeVariable) ta;
assert
tv.getName().equals("T") :
"mc1t: Name of the type arg of C1<T> is T, not " + tv.getName();
bs = tv.getBounds();
assert
bs.length == 1 :
"mc1t: The type argument of C1<T> should have one bound";
assert
bs[0] == Object.class :
"mc1t: The bound of the type arg of C1<T> should be Object";
Type p3_mc1t = pt_mc1t[2];
assert
p3_mc1t == cls :
"Type of parameter 3 of mc1t is C1";
Type[] pt_mc1 = mc1.getGenericParameterTypes();
assert
pt_mc1.length == 0 :
"C1.mc1 has zero parameters";
Type[] pt_mt = mt.getGenericParameterTypes();
assert
pt_mt.length == 1 :
"C1.mt has one parameter";
Type p_mt = pt_mt[0];
assert
p_mt instanceof TypeVariable :
"The generic type of the parameter of mt(T) is a type variable";
tv = (TypeVariable) p_mt;
assert
tv.getName().equals("T") :
"The name of the type parameter of mt is T, not " + tv.getName();
bs = tv.getBounds();
assert
bs.length == 1 :
"T should have one bound";
assert
bs[0] == Object.class :
"The bound of T should be Object";
Type[] et_mc1t = mc1t.getGenericExceptionTypes();
assert
et_mc1t.length == 0 :
"Method C1.mc1t should have no generic exception types";
Type[] et_mc1 = mc1.getGenericExceptionTypes();
assert
et_mc1.length == 0 :
"Method C1.mc1 should have no generic exception types";
Type[] et_mt = mt.getGenericExceptionTypes();
assert
et_mt.length == 0 :
"Method C1.mt should have no generic exception types";
TypeVariable[] tv_mc1t = mc1t.getTypeParameters();
assert
tv_mc1t.length == 0 :
"Method C1.mc1t should have no type parameters";
TypeVariable[] tv_mc1 = mc1.getTypeParameters();
assert
tv_mc1.length == 0 :
"Method C1.mc1 should have no type parameters";
TypeVariable[] tv_mt = mt.getTypeParameters();
assert
tv_mt.length == 0 :
"Method C1.mt should have no type parameters";
}
static void testFields() throws NoSuchFieldException{
System.out.println("testing fields");
Field ft = cls. getField("ft");
Field fc1t = cls. getField("fc1t");
Field fc1 = cls. getField("fc1");
Type gt_ft = ft.getGenericType();
assert
gt_ft instanceof TypeVariable :
"The generic type of C1.ft is a type variable";
TypeVariable tv = (TypeVariable) gt_ft;
assert
tv.getName().equals("T") :
"The name of the type of ft is T, not " + tv.getName();
Type[] bs = tv.getBounds();
assert
bs.length == 1 :
"The type of ft should have one bound";
assert
bs[0] == Object.class :
"The bound of the type of ft should be Object";
Type gt_fc1t = fc1t.getGenericType();
assert
gt_fc1t instanceof ParameterizedType :
"The generic type of C1.fc1t is a parameterized type";
ParameterizedType pt = (ParameterizedType) gt_fc1t;
assert
pt.getRawType() == cls :
"Type of C1.fc1t is instantiation of C1";
assert
pt.getOwnerType() == null :
"Type of C1.fc1t is has null owner";
Type[] tas = pt.getActualTypeArguments();
assert
tas.length == 1 :
"The type of fc1t has one type argument";
Type ta = tas[0];
assert
ta instanceof TypeVariable :
"The actual type arg of C1<T> is a type variable";
tv = (TypeVariable) ta;
assert
tv.getName().equals("T") :
"The name of the type arg of C1<T> is T, not " + tv.getName();
bs = tv.getBounds();
assert
bs.length == 1 :
"The type argument of C1<T> should have one bound";
assert
bs[0] == Object.class :
"The bound of the type arg of C1<T> should be Object";
Type gt_fc1 = fc1.getGenericType();
assert
gt_fc1 == cls :
" Type of C1.fc1 should be C1";
}
static void testConstructor() throws NoSuchMethodException {
System.out.println("testing constructors");
Class[] params = new Class[1];
params[0] = Object.class;
Constructor<C1> con = cls.getDeclaredConstructor(params);
Type[] pt_con = con.getGenericParameterTypes();
assert
pt_con.length == 1 :
"Constructor C1(T) should have one generic parameter type";
Type pt = pt_con[0];
assert
pt instanceof TypeVariable :
"The generic type of the parameter of C1(T) is a type variable";
TypeVariable tv = (TypeVariable) pt;
assert
tv.getName().equals("T") :
"The name of the type parameter of C is T, not " + tv.getName();
Type[] bs = tv.getBounds();
assert
bs.length == 1 :
"T should have one bound";
assert
bs[0] == Object.class :
"The bound of T should be Object";
Type[] et_con = con.getGenericExceptionTypes();
assert
et_con.length == 0 :
"Constructor C1(T) should have no generic exception types";
TypeVariable[] tv_con = con.getTypeParameters();
assert
tv_con.length == 0 :
"Constructor C1(T) should have no type parameters";
}
}

View file

@ -0,0 +1,653 @@
/*
* 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 4891872
* @summary Some tests for the generic core reflection api.
* @author Gilad Bracha
* @compile TestC2.java
* @run main/othervm -ea TestC2
*/
import java.lang.reflect.*;
abstract class C0<T> {
public T ft;
public C0<T> fc1t;
public C0 fc1;
public C0(){}
public C0(T t) {}
public abstract C0<T> mc1t(T t, C0<T> c1t, C0 c1);
public abstract C0 mc1();
public abstract T mt(T t);
}
interface I1<X1, X2> extends I3 {
X1 foo(X2 x2);
}
interface I2<E1, E2 extends Throwable, E3> {
E1 bar(E3 e3) throws E2;
}
interface I3 {
}
abstract class C2<T1 extends C2<T1, T2, T3>, T2 extends C0<T2>,
T3 extends Throwable>
extends C0<T1>
implements I1<T1, T2>, I2<T1, T3, T2>, I3
{
public T1 ft;
public C0<String> fc1t;
public C0 fc1;
public int fi;
public C2(T2 t2) {}
public <T> C2(T t) {}
public <T1, T2, T3, T4> C2(T1 t1, T2 t2, T4 t4) {}
public C2() throws T3 {}
public abstract <T> C0<T> mc1t(T3 t3, C0<T> c1t, C0 c1);
public abstract <E, R> C0 mc1(E e);
public abstract T1 mt(T2 t);
}
public class TestC2 {
static Class<C2> cls = C2.class;
public static void main(String[] args) throws Throwable {
testSuperclass();
testSuperInterfaces();
testTypeParameters();
testMethods();
testConstructors();
testFields();
}
static void testSuperclass() {
System.out.println("testing superclass");
Type sc = cls.getGenericSuperclass();
assert
sc instanceof ParameterizedType :
"Superclass of C2 should be a parameterized type";
ParameterizedType psc = (ParameterizedType) sc;
assert
((psc.getRawType() == C0.class) ) :
"The raw generic superclass of C2 should be C0";
Type[] tas = psc.getActualTypeArguments();
assert
tas.length == 1 :
"Superclass of C2 should have one type argument";
Type t = tas[0];
assert
t instanceof TypeVariable :
"Type argument to superclass of C2 should be a type variable";
TypeVariable tv = (TypeVariable) t;
assert
tv.getName().equals("T1") :
"Name of type argument to superclass of C2 should be T1";
Type[] bs = tv.getBounds();
assert
bs.length == 1 :
"T1 has one bound (superclass)";
t = bs[0];
assert
t instanceof ParameterizedType :
"Bound of C0 should be a parameterized type";
ParameterizedType pt = (ParameterizedType) t;
assert
((pt.getRawType() == C2.class) ) :
"The raw bound of T1 should be C2";
tas = pt.getActualTypeArguments();
assert
tas.length == 3 :
"Bound of T1 should have three type arguments";
assert
tas[0] instanceof TypeVariable :
"First argument to bound of T1 is a type variable";
assert
tas[1] instanceof TypeVariable :
"Second argument to bound of T1 is a type variable";
assert
tas[2] instanceof TypeVariable :
"Third argument to bound of T1 is a type variable";
TypeVariable tv1 = (TypeVariable) tas[0];
TypeVariable tv2 = (TypeVariable) tas[1];
TypeVariable tv3 = (TypeVariable) tas[2];
assert
tv1.getName().equals("T1"):
"First type arg to bound of T1 is T1";
assert
tv2.getName().equals("T2"):
"Seconmd type arg to bound of T1 is T2";
assert
tv3.getName().equals("T3"):
"Third type arg to bound of T1 is T3";
}
static void testSuperInterfaces() {
System.out.println("testing superinterfaces");
Type[] sis = cls.getGenericInterfaces();
assert
((sis.length == 3)):
"C2 should have three generic superinterfaces";
Type t = sis[0];
assert
t instanceof ParameterizedType :
"First superinterface of C2 should be a parameterized type";
ParameterizedType pt = (ParameterizedType) t;
assert
pt.getRawType() == I1.class :
"First super interface of C2 is instantiation of I1";
Type[] tas = pt.getActualTypeArguments();
assert
tas.length == 2 :
"First super interface of C2 has 2 type arguments";
t = sis[1];
assert
t instanceof ParameterizedType :
"Second superinterface of C2 should be a parameterized type";
pt = (ParameterizedType) t;
assert
pt.getRawType() == I2.class :
"Second super interface of C2 is instantiation of I2";
tas = pt.getActualTypeArguments();
assert
tas.length == 3 :
"Second super interface of C2 has 3 type arguments";
t = sis[2];
assert
t == I3.class :
"Third superinterface of C2 is I3";
// Test interfaces themselves
TypeVariable[] tvs = I1.class.getTypeParameters();
assert
tvs.length == 2 :
"I3 has two formal type parameters";
assert
tvs[0].getName().equals("X1") :
"Name of first formal type arg of I1 is X1";
assert
tvs[1].getName().equals("X2") :
"Name of second formal type arg of I1 is X2";
assert
I1.class.getGenericSuperclass() == I1.class.getSuperclass() :
"The generic and non-generic superclasses of an interface must be the same";
sis = I1.class.getGenericInterfaces();
assert
sis.length == 1 :
"I1 has one generic superinterface";
assert
sis[0] == I3.class :
"Superinterface of I1 is I3";
tvs = I2.class.getTypeParameters();
assert
tvs.length == 3 :
"I3 has three formal type parameters";
assert
tvs[0].getName().equals("E1") :
"Name of first formal type arg of I2 is E1";
assert
tvs[1].getName().equals("E2") :
"Name of second formal type arg of I2 is E2";
assert
tvs[2].getName().equals("E3") :
"Name of third formal type arg of I2 is E3";
assert
I2.class.getGenericSuperclass() == I2.class.getSuperclass() :
"The generic and non-generic superclasses of an interface must be the same";
tvs = I3.class.getTypeParameters();
assert
tvs.length == 0 :
"I3 has no formal type parameters";
assert
I3.class.getGenericSuperclass() == I3.class.getSuperclass() :
"The generic and non-generic superclasses of an interface must be the same";
}
static void testTypeParameters() {
System.out.println("testing type parameters");
TypeVariable[] tvs = cls.getTypeParameters();
assert
tvs.length == 3 :
"C2 should have three type parameters";
TypeVariable tv = tvs[0];
Type[] bs = tv.getBounds();
assert
bs.length == 1 :
"T1 should have one bound";
assert
bs[0] instanceof ParameterizedType :
"The bound of T1 should be a parameterized type";
tv = tvs[1];
bs = tv.getBounds();
assert
bs.length == 1 :
"T2 should have one bound";
assert
bs[0] instanceof ParameterizedType :
"The bound of T2 should be a parameterized type";
tv = tvs[2];
bs = tv.getBounds();
assert
bs.length == 1 :
"T3 should have one bound";
assert
bs[0] == Throwable.class :
"The bound of T3 should be Throwable";
}
static void testMethods() throws NoSuchMethodException {
System.out.println("testing methods");
Class[] params1 = new Class[3];
params1[0] = Throwable.class;
params1[1] = C0.class;
params1[2] = C0.class;
Class[] params2 = new Class[1];
params2[0] = Object.class;
Class[] params3 = new Class[1];
params3[0] = C0.class;
Method mc1t = cls.getMethod("mc1t", params1);
Method mc1 = cls.getMethod("mc1", params2);
Method mt = cls.getMethod("mt", params3);
Type rt_mc1t = mc1t.getGenericReturnType();
assert
rt_mc1t instanceof ParameterizedType :
"The return type of mc1t should be a parameterized type";
ParameterizedType pt = (ParameterizedType) rt_mc1t;
assert
pt.getRawType() == C0.class :
"The raw return type of mc1t should be C0";
Type[] tas = pt.getActualTypeArguments();
assert
tas.length == 1 :
"Return type of mc1t should have one type argument";
assert
tas[0] instanceof TypeVariable :
"Type argument of return type of mc1t is a type variable";
Type rt_mc1 = mc1.getGenericReturnType();
assert
rt_mc1 == C0.class :
"Return type of mc1 is C0";
Type rt_mt = mt.getGenericReturnType();
assert
rt_mt instanceof TypeVariable :
"Return type of mt is a type variable";
Type[] pt_mc1t = mc1t.getGenericParameterTypes();
assert
pt_mc1t.length == 3 :
"C0.mc1t has three parameters";
Type p1_mc1t = pt_mc1t[0];
assert p1_mc1t != null;
assert
p1_mc1t instanceof TypeVariable :
"Generic type of the 1st parameter of mc1t(T) is a type variable";
TypeVariable tv = (TypeVariable) p1_mc1t;
assert
tv.getName().equals("T3") :
"Name of 1st type parameter of mc1t is T3, not " + tv.getName();
Type[] bs = tv.getBounds();
assert
bs.length == 1 :
"T3 should have one bound (mc1t)";
assert
bs[0] == Throwable.class :
"The bound of T3 should be Throwable(mc1t)";
Type p2_mc1t = pt_mc1t[1];
assert
p2_mc1t instanceof ParameterizedType :
"The type of parameter 2 of mc1t is a parameterized type";
pt = (ParameterizedType) p2_mc1t;
assert
pt.getRawType() == C0.class :
"Type of parameter 2 of mc1t is instantiation of C0";
assert
pt.getOwnerType() == null :
"Type of parameter 2 of mc1t is has null owner";
tas = pt.getActualTypeArguments();
assert
tas.length == 1 :
"The type of parameter 2 of mc1t has one type argument";
Type ta = tas[0];
assert
ta instanceof TypeVariable :
"The actual type arg of C0<T> is a type variable (mc1t)";
tv = (TypeVariable) ta;
assert
tv.getName().equals("T") :
"mc1t: Name of the type arg of C0<T> is T, not " + tv.getName();
bs = tv.getBounds();
assert
bs.length == 1 :
"mc1t: The type argument of C0<T> should have one bound";
assert
bs[0] == Object.class :
"mc1t: The bound of the type arg of C0<T> should be Object";
Type p3_mc1t = pt_mc1t[2];
assert
p3_mc1t == C0.class :
"Type of parameter 3 of mc1t is C0";
Type[] pt_mc1 = mc1.getGenericParameterTypes();
assert
pt_mc1.length == 1 :
"C2.mc1 has one parameter";
Type[] pt_mt = mt.getGenericParameterTypes();
assert
pt_mt.length == 1 :
"C2.mt has one parameter";
Type p_mt = pt_mt[0];
assert
p_mt instanceof TypeVariable :
"The generic type of the parameter of mt(T) is a type variable";
tv = (TypeVariable) p_mt;
assert
tv.getName().equals("T2") :
"The name of the type parameter of mt is T2, not " + tv.getName();
bs = tv.getBounds();
assert
bs.length == 1 :
"T2 should have one bound";
assert
bs[0] instanceof ParameterizedType:
"The bound of T2 should be parameterized type";
Type[] et_mc1t = mc1t.getGenericExceptionTypes();
assert
et_mc1t.length == 0 :
"Method C0.mc1t should have no generic exception types";
Type[] et_mc1 = mc1.getGenericExceptionTypes();
assert
et_mc1.length == 0 :
"Method C0.mc1 should have no generic exception types";
Type[] et_mt = mt.getGenericExceptionTypes();
assert
et_mt.length == 0 :
"Method C0.mt should have no generic exception types";
TypeVariable[] tv_mc1t = mc1t.getTypeParameters();
assert
tv_mc1t.length == 1 :
"Method C2.mc1t should have one type parameter";
TypeVariable[] tv_mc1 = mc1.getTypeParameters();
assert
tv_mc1.length == 2 :
"Method C2.mc1 should have two type parameters";
TypeVariable[] tv_mt = mt.getTypeParameters();
assert
tv_mt.length == 0 :
"Method C2.mt should have no type parameters";
}
static void testFields() throws NoSuchFieldException{
System.out.println("testing fields");
Field ft = cls. getField("ft");
Field fc1t = cls. getField("fc1t");
Field fc1 = cls. getField("fc1");
Field fi = cls. getField("fi");
Type gt_ft = ft.getGenericType();
assert
gt_ft instanceof TypeVariable :
"The generic type of C0.ft is a type variable";
TypeVariable tv = (TypeVariable) gt_ft;
assert
tv.getName().equals("T1") :
"The name of the type of ft is T1, not " + tv.getName();
Type[] bs = tv.getBounds();
assert
bs.length == 1 :
"The type of ft should have one bound";
Type gt_fc1t = fc1t.getGenericType();
assert
gt_fc1t instanceof ParameterizedType :
"The generic type of C0.fc1t is a parameterized type";
ParameterizedType pt = (ParameterizedType) gt_fc1t;
assert
pt.getRawType() == C0.class :
"Type of C2.fc1t is an instantiation of C0";
assert
pt.getOwnerType() == null :
"Type of C2.fc1t is has null owner";
Type[] tas = pt.getActualTypeArguments();
assert
tas.length == 1 :
"The type of fc1t has one type argument";
Type ta = tas[0];
assert
ta == String.class :
"The actual type arg of C0<String> is String";
Type gt_fc1 = fc1.getGenericType();
assert
gt_fc1 == C0.class :
" Type of C2.fc1 should be C0";
Type gt_fi = fi.getGenericType();
assert
gt_fi == int.class:
" Type of C2.fi should be int";
}
static void testConstructors() throws NoSuchMethodException {
System.out.println("testing constructors");
Class[] params1 = new Class[1];
params1[0] = C0.class;
Constructor<C2> con = cls.getDeclaredConstructor(params1);
Type[] pt_con = con.getGenericParameterTypes();
assert
pt_con.length == 1 :
"Constructor C0(T) should have one generic parameter type";
Type pt = pt_con[0];
assert
pt instanceof TypeVariable :
"The generic type of the parameter of C0(T2) is a type variable";
TypeVariable tv = (TypeVariable) pt;
assert
tv.getName().equals("T2") :
"The name of the type parameter of C2 is T2, not " + tv.getName();
Type[] bs = tv.getBounds();
assert
bs.length == 1 :
"T should have one bound";
Type[] et_con = con.getGenericExceptionTypes();
assert
et_con.length == 0 :
"Constructor C2(T2) should have no generic exception types";
TypeVariable[] tv_con = con.getTypeParameters();
assert
tv_con.length == 0 :
"Constructor C2(T2) should have no type parameters";
Class[] params2 = new Class[1];
params2[0] = Object.class;
con = cls.getDeclaredConstructor(params2);
pt_con = con.getGenericParameterTypes();
assert
pt_con.length == 1 :
"Constructor C0(T) should have one generic parameter type";
pt = pt_con[0];
assert
pt instanceof TypeVariable :
"The generic type of the parameter of C2(T) is a type variable";
tv = (TypeVariable) pt;
assert
tv.getName().equals("T") :
"The name of the type parameter of C2 is T, not " + tv.getName();
bs = tv.getBounds();
assert
bs.length == 1 :
"T should have one bound";
et_con = con.getGenericExceptionTypes();
assert
et_con.length == 0 :
"Constructor C2(T) should have no generic exception types";
tv_con = con.getTypeParameters();
assert
tv_con.length == 1 :
"Constructor C2(T) should have one type parameter";
Class[] params3 = new Class[3];
params3[0] = Object.class;
params3[1] = Object.class;
params3[2] = Object.class;
con = cls.getDeclaredConstructor(params3);
pt_con = con.getGenericParameterTypes();
assert
pt_con.length == 3 :
"Constructor C2(T1,T2,T4) should have three generic parameter types";
pt = pt_con[0];
assert
pt instanceof TypeVariable :
"The generic type of the first parameter of C2(T1,T2,T4) is a type variable";
tv = (TypeVariable) pt;
assert
tv.getName().equals("T1") :
"The name of the type parameter of C2(T1,T2,T4) is T1, not " + tv.getName();
bs = tv.getBounds();
assert
bs.length == 1 :
"T should have one bound";
et_con = con.getGenericExceptionTypes();
assert
et_con.length == 0 :
"Constructor C2(T1,T2,T4) should have no generic exception types";
tv_con = con.getTypeParameters();
assert
tv_con.length == 4 :
"Constructor C2(T1,T2,T4) should have four type parameters";
Class[] params4 = new Class[0];
con = cls.getDeclaredConstructor(params4);
pt_con = con.getGenericParameterTypes();
assert
pt_con.length == 0 :
"Constructor C2() should have no generic parameter types";
et_con = con.getGenericExceptionTypes();
assert
et_con.length == 1 :
"Constructor C2() should have one generic exception type";
tv_con = con.getTypeParameters();
assert
tv_con.length == 0 :
"Constructor C2() should have no type parameters";
}
}

View file

@ -0,0 +1,133 @@
/*
* Copyright (c) 2016, 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 8054213
* @summary Check that toString method works properly for generic return type
* obtained via reflection
* @run main TestGenericReturnTypeToString
*/
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
import java.util.List;
public class TestGenericReturnTypeToString {
public static void main(String[] args) {
boolean hasFailures = false;
for (Method method : TestGenericReturnTypeToString.class.getMethods()) {
if (method.isAnnotationPresent(ExpectedGenericString.class)) {
ExpectedGenericString es = method.getAnnotation
(ExpectedGenericString.class);
String result = method.getGenericReturnType().toString();
if (!es.value().equals(result)) {
hasFailures = true;
System.err.println("Unexpected result of " +
"getGenericReturnType().toString() " +
" for " + method.getName()
+ " expected: " + es.value() + " actual: " + result);
}
}
if (hasFailures) {
throw new RuntimeException("Test failed");
}
}
}
@ExpectedGenericString("TestGenericReturnTypeToString$" +
"FirstInnerClassGeneric<Dummy>$SecondInnerClassGeneric<Dummy>")
public FirstInnerClassGeneric<Dummy>.SecondInnerClassGeneric<Dummy> foo1() {
return null;
}
@ExpectedGenericString("TestGenericReturnTypeToString$" +
"FirstInnerClassGeneric<Dummy>$SecondInnerClass")
public FirstInnerClassGeneric<Dummy>.SecondInnerClass foo2() {
return null;
}
@ExpectedGenericString("TestGenericReturnTypeToString$" +
"FirstInnerClass$SecondInnerClassGeneric<Dummy>")
public FirstInnerClass.SecondInnerClassGeneric<Dummy> foo3() {
return null;
}
@ExpectedGenericString("class TestGenericReturnTypeToString$" +
"FirstInnerClass$SecondInnerClass")
public FirstInnerClass.SecondInnerClass foo4() {
return null;
}
@ExpectedGenericString(
"java.util.List<java.lang.String>")
public java.util.List<java.lang.String> foo5() {
return null;
}
@ExpectedGenericString("interface TestGenericReturnTypeToString$" +
"FirstInnerClass$Interface")
public FirstInnerClass.Interface foo6() {
return null;
}
@ExpectedGenericString("TestGenericReturnTypeToString$" +
"FirstInnerClass$InterfaceGeneric<Dummy>")
public FirstInnerClass.InterfaceGeneric<Dummy> foo7() {
return null;
}
public static class FirstInnerClass {
public class SecondInnerClassGeneric<T> {
}
public class SecondInnerClass {
}
interface Interface {
}
interface InterfaceGeneric<T> {
}
}
public class FirstInnerClassGeneric<T> {
public class SecondInnerClassGeneric<T> {
}
public class SecondInnerClass {
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface ExpectedGenericString {
String value();
}
class Dummy {
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 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
* @library /test/lib
* @bug 8337302
* @summary Tests that an exception is thrown if a type variable is not declared
*/
import jdk.test.lib.ByteCodeLoader;
import java.lang.classfile.ClassFile;
import java.lang.classfile.Signature;
import java.lang.classfile.attribute.SignatureAttribute;
import java.lang.constant.ClassDesc;
import java.lang.reflect.AccessFlag;
import java.lang.reflect.Type;
public class TestMissingTypeVariable {
public static void main(String[] args) throws Exception {
ClassFile cf = ClassFile.of();
byte[] bytes = cf.build(
ClassDesc.of("sample.MissingVariable"),
classBuilder -> {
classBuilder.withSuperclass(ClassDesc.of("java.lang.Object"));
classBuilder.withFlags(AccessFlag.PUBLIC);
classBuilder.withField("f",
ClassDesc.of("java.lang.Object"),
fieldBuilder -> fieldBuilder.withFlags(AccessFlag.PUBLIC).with(SignatureAttribute.of(Signature.parseFrom("TA;"))));
});
/*
package sample;
public class MissingVariable {
public A f; // undeclared type variable
}
*/
Class<?> missing = ByteCodeLoader.load("sample.MissingVariable", bytes);
try {
Type type = missing.getField("f").getGenericType();
throw new IllegalStateException("Expected TypeNotPresentException but got: " + type);
} catch (TypeNotPresentException e) {
if (!"A".equals(e.typeName())) {
throw new IllegalStateException("Unexpected name: " + e.typeName());
}
}
}
}

View file

@ -0,0 +1,207 @@
/*
* 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 4891872
* @summary Some tests for the generic core reflection api.
* @author Gilad Bracha
* @compile TestN1.java
* @run main/othervm -ea TestN1
*/
import java.lang.reflect.*;
class N1<T1, T2> {
public Inner1 i1;
public Inner2 i2;
public Inner2<? super Character> i2sc;
public class Inner1 {
}
public class Inner2<T1> {
public boolean x;
public byte b;
public short s;
public char c;
public int i;
public long l;
public float f;
public double d;
public boolean[] xa;
public byte[] ba;
public short[] sa;
public char[] ca;
public int[] ia;
public long[] la;
public float[] fa;
public double[] da;
}
public class Inner3<X1, X2, X3> {
X1 x1;
Inner3(X1 x1, X2 x2, X3 x3, T1 t1, T2 t2) {}
<T, R, S> Inner3(T t, R r, S s, X1 x1) {}
int shazam(boolean b, short s, int[] ia, Object[] oa, Inner1 i1,
Inner1 i1a, InnerInner<String,
Inner3<Object, String, Object[]>> ii)
{ return 3;}
public class InnerInner<T2, X2> {
boolean b;
Inner2<X2> i2x;
void foo(X3 x3){}
<X3> X3[] bar(X1 x1, X3[] x3, T1 t1) { return x3;}
N1<X1, X2> baz(N1<X1, X2> n1) { return n1;}
N1<?, ?> bam(N1<T1, X2> n1) { return n1;}
N1<? extends T1, ?> boom(N1<T1, X2> n1) { return n1;}
}
}
}
public class TestN1 {
static Class<N1> cls = N1.class;
public static void main(String[] args) throws Throwable {
testTypeParameters();
testInner1();
testInner2();
testInner3();
}
static void testTypeParameters() {
System.out.println("testing type parameters");
TypeVariable[] tvs = cls.getTypeParameters();
assert
tvs.length == 2 :
"N1 should have two type parameters";
}
static void testInner1() {
System.out.println("testing non-generic inner class");
Class in1 = N1.Inner1.class;
TypeVariable[] tvs = in1.getTypeParameters();
assert
tvs.length == 0 :
"N1.Inner2 should have no type parameters";
}
static void testInner2() throws NoSuchFieldException {
System.out.println("testing generic inner class 1");
Class in1 = N1.Inner2.class;
TypeVariable[] tvs = in1.getTypeParameters();
assert
tvs.length == 1 :
"N1.Inner2 should have one type parameter";
assert
in1.getField("x").getGenericType() == boolean.class :
"Type of Inner2.x should be boolean";
assert
in1.getField("b").getGenericType() == byte.class :
"Type of Inner2.b should be byte";
assert
in1.getField("s").getGenericType() == short.class :
"Type of Inner2.s should be short";
assert
in1.getField("c").getGenericType() == char.class :
"Type of Inner2.x should be char";
assert
in1.getField("i").getGenericType() == int.class :
"Type of Inner2.i should be int";
assert
in1.getField("l").getGenericType() == long.class :
"Type of Inner2.l should be long";
assert
in1.getField("f").getGenericType() == float.class :
"Type of Inner2.f should be float";
assert
in1.getField("d").getGenericType() == double.class :
"Type of Inner2.d should be double";
assert
in1.getField("xa").getGenericType() == boolean[].class :
"Type of Inner2.xa should be boolean[]";
assert
in1.getField("ba").getGenericType() == byte[].class :
"Type of Inner2.ba should be byte[]";
assert
in1.getField("sa").getGenericType() == short[].class :
"Type of Inner2.sa should be short[]";
assert
in1.getField("ca").getGenericType() == char[].class :
"Type of Inner2.xa should be char[]";
assert
in1.getField("ia").getGenericType() == int[].class :
"Type of Inner2.ia should be int[]";
assert
in1.getField("la").getGenericType() == long[].class :
"Type of Inner2.la should be long[]";
assert
in1.getField("fa").getGenericType() == float[].class :
"Type of Inner2.fa should be float[]";
assert
in1.getField("da").getGenericType() == double[].class :
"Type of Inner2.da should be double[]";
}
static void testInner3() {
System.out.println("testing generic inner class 3");
Class in1 = N1.Inner3.class;
TypeVariable[] tvs = in1.getTypeParameters();
assert
tvs.length == 3 :
"N1.Inner2 should have three type parameters";
}
}

View file

@ -0,0 +1,147 @@
/*
* 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 5061485
* @summary Test sematics of ParameterizedType.equals
*/
import java.util.*;
import java.lang.reflect.*;
public class TestParameterizedType {
public <T> T genericMethod0() {
return null;
}
public <T> Set<T> genericMethod1() {
return null;
}
public <T> Set<T> genericMethod2() {
return null;
}
public <S> List<S> genericMethod3() {
return null;
}
public <X, Y> Map<X, Y> genericMethod4() {
return null;
}
public <T> T[] genericMethod5() {
return null;
}
public <T> T[] genericMethod6() {
return null;
}
public Set<? extends Cloneable> genericMethod7() {
return null;
}
public Set<? super Number> genericMethod8() {
return null;
}
public Set<?> genericMethod9() {
return null;
}
static List<Type> createTypes() throws Exception {
List<Type> typeList = new ArrayList<Type>(3);
String[] methodNames = {"genericMethod0",
"genericMethod1",
"genericMethod2",
"genericMethod3",
"genericMethod4",
"genericMethod5",
"genericMethod6",
"genericMethod7",
"genericMethod8",
"genericMethod9",
};
for(String s : methodNames) {
Type t = TestParameterizedType.class.getDeclaredMethod(s).getGenericReturnType();
// if (! (t instanceof ParameterizedType))
// throw new RuntimeException("Unexpected kind of return type");
typeList.add(t);
}
return typeList;
}
static boolean testReflexes(List<Type> typeList) {
for(Type t : typeList) {
if (! t.equals(t) ) {
System.err.printf("Bad reflexes for%s %s%n", t, t.getClass());
return true;
}
}
return false;
}
public static void main(String[] argv) throws Exception {
boolean failed = false;
List<Type> take1 = createTypes();
List<Type> take2 = createTypes();
// Test reflexivity
failed = failed | testReflexes(take1);
failed = failed | testReflexes(take2);
for(int i = 0; i < take1.size(); i++) {
Type type1 = take1.get(i);
for(int j = 0; j < take2.size(); j++) {
Type type2 = take2.get(j);
if (i == j) {
// corresponding types should be .equals
if (!type1.equals(type2) ) {
failed = true;
System.err.printf("Unexpected inequality: [%d, %d] %n\t%s%n\t%s%n",
i, j, type1, type2);
}
} else {
// non-corresponding types should *not* be .equals
if (type1.equals(type2) ) {
failed = true;
System.err.printf("Unexpected equality: [%d, %d] %n\t%s%n\t%s%n",
i, j, type1, type2);
}
}
}
}
if (failed)
throw new RuntimeException("Bad equality on ParameterizedTypes");
}
}

View file

@ -0,0 +1,156 @@
/*
* Copyright (c) 2008, 2010, 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 5041784
* @summary Check that plain arrays like String[] are never represented as
* GenericArrayType.
* @author Eamonn McManus
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class TestPlainArrayNotGeneric {
public String[] m1(List<String> p1) {return null;}
public List<String> m2(String[] p1) {return null;}
public void m3(List<String> p1, String[] p2) {}
public void m4(List<String[]> p1) {}
public TestPlainArrayNotGeneric(List<String[]> p1) {}
public TestPlainArrayNotGeneric(List<String> p1, String[] p2) {}
public <T extends List<String[]>> T m5(T p1) {return null;}
public <T extends Object> T[] m6(T[] p1, List<T[]> p2) {return null;}
public List<? extends Object[]> m6(List<? extends Object[]> p1) {return null;}
public <T extends List<? extends Object[]>> T m7(T[] p1) {return null;}
public List<? super Object[]> m8(List<? super Object[]> p1) {return null;}
public <T extends List<? super Object[]>> T[] m9(T[] p1) {return null;}
public static interface XMap extends Map<List<String[]>, String[]> {}
public static interface YMap<K extends List<String[]>, V>
extends Map<K[], V[]> {}
private static String lastFailure;
private static int failureCount;
public static void main(String[] args) throws Exception {
checkClass(TestPlainArrayNotGeneric.class);
if (failureCount == 0)
System.out.println("TEST PASSED");
else
throw new Exception("TEST FAILED: Last failure: " + lastFailure);
}
private static void checkClass(Class<?> c) throws Exception {
Method[] methods = c.getMethods();
for (Method m : methods) {
check(m.getGenericReturnType(), "return type of method " + m);
check(m.getGenericParameterTypes(), "parameter", "method " + m);
check(m.getTypeParameters(), "type parameter", "method " + m);
}
Constructor[] constructors = c.getConstructors();
for (Constructor constr : constructors) {
check(constr.getGenericParameterTypes(), "parameter",
"constructor " + constr);
check(constr.getTypeParameters(), "type parameter",
"constructor " + constr);
}
Class<?>[] inners = c.getDeclaredClasses();
for (Class inner : inners)
checkClass(inner);
}
private static void check(Type[] types, String elementKind, String what) {
for (int i = 0; i < types.length; i++) {
Type t = types[i];
check(t, elementKind + " " + (i+1) + " of " + what);
}
}
private static final Set<Type> checking = new HashSet<>();
private static void check(Type t, String what) {
if (t == null || !checking.add(t))
return;
// Avoid infinite recursion. t can be null e.g. for superclass of Object.
try {
check2(t, what);
} finally {
checking.remove(t);
}
}
private static void check2(Type t, String what) {
if (t instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) t;
check(pt.getActualTypeArguments(), "type argument", what);
} else if (t instanceof TypeVariable) {
TypeVariable<?> tv = (TypeVariable<?>) t;
check(tv.getBounds(), "bound", what);
GenericDeclaration gd = tv.getGenericDeclaration();
if (gd instanceof Type)
check((Type) gd, "declaration containing " + what);
} else if (t instanceof WildcardType) {
WildcardType wt = (WildcardType) t;
check(wt.getLowerBounds(), "lower bound", "wildcard type in " + what);
check(wt.getUpperBounds(), "upper bound", "wildcard type in " + what);
} else if (t instanceof Class<?>) {
Class<?> c = (Class<?>) t;
check(c.getGenericInterfaces(), "superinterface", c.toString());
check(c.getGenericSuperclass(), "superclass of " + c);
check(c.getTypeParameters(), "type parameter", c.toString());
} else if (t instanceof GenericArrayType) {
GenericArrayType gat = (GenericArrayType) t;
Type comp = gat.getGenericComponentType();
if (comp instanceof Class) {
fail("Type " + t + " uses GenericArrayType when plain " +
"array would do, in " + what);
} else
check(comp, "component type of " + what);
} else {
fail("TEST BUG: mutant Type " + t + " (a " + t.getClass().getName() + ")");
}
}
private static void fail(String why) {
System.out.println("FAIL: " + why);
lastFailure = why;
failureCount++;
}
}

View file

@ -0,0 +1,135 @@
/*
* Copyright 2014 Google Inc. 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 8062771 8016236
* @summary Test publication of Class objects via a data race
* @run junit ThreadSafety
*/
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.Callable;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
/**
* A test resulting from an attempt to repro this failure (in guice):
*
* java.lang.NullPointerException
* at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125)
* at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
* at sun.reflect.generics.repository.ClassRepository.getSuperclass(ClassRepository.java:84)
* at java.lang.Class.getGenericSuperclass(Class.java:692)
* at com.google.inject.TypeLiteral.getSuperclassTypeParameter(TypeLiteral.java:99)
* at com.google.inject.TypeLiteral.<init>(TypeLiteral.java:79)
*
* However, as one would expect with thread safety problems in reflection, these
* are very hard to reproduce. This very test has never been observed to fail,
* but a similar test has been observed to fail about once in 2000 executions
* (about once every 6 CPU-hours), in jdk7 only. It appears to be fixed in jdk8+ by:
*
* 8016236: Class.getGenericInterfaces performance improvement.
* (by making Class.genericInfo volatile)
*/
public class ThreadSafety {
public static class EmptyClass {
public static class EmptyGenericSuperclass<T> {}
public static class EmptyGenericSubclass<T> extends EmptyGenericSuperclass<T> {}
}
/** published via data race */
private Class<?> racyClass = Object.class;
private Class<?> createNewEmptyGenericSubclassClass() throws Exception {
String[] cpaths = System.getProperty("test.classes", ".")
.split(File.pathSeparator);
URL[] urls = new URL[cpaths.length];
for (int i=0; i < cpaths.length; i++) {
urls[i] = Paths.get(cpaths[i]).toUri().toURL();
}
URLClassLoader ucl = new URLClassLoader(urls, null);
return Class.forName("ThreadSafety$EmptyClass$EmptyGenericSubclass", true, ucl);
}
@Test
public void testRacy_getGenericSuperclass() throws Exception {
final int nThreads = 10;
final int iterations = 30;
final int timeout = 10;
final CyclicBarrier newCycle = new CyclicBarrier(nThreads);
final Callable<Void> task = new Callable<Void>() {
public Void call() throws Exception {
for (int i = 0; i < iterations; i++) {
final int threadId;
try {
threadId = newCycle.await(timeout, SECONDS);
} catch (BrokenBarrierException e) {
return null;
}
for (int j = 0; j < iterations; j++) {
// one thread publishes the class object via a data
// race, for the other threads to consume.
if (threadId == 0) {
racyClass = createNewEmptyGenericSubclassClass();
} else {
racyClass.getGenericSuperclass();
}
}
}
return null;
}};
final ExecutorService pool = Executors.newFixedThreadPool(nThreads);
try {
for (Future<Void> future :
pool.invokeAll(Collections.nCopies(nThreads, task))) {
try {
future.get(iterations * timeout, SECONDS);
} catch (ExecutionException e) {
// ignore "collateral damage"
if (!(e.getCause() instanceof BrokenBarrierException)
&&
!(e.getCause() instanceof TimeoutException)) {
throw e;
}
}
}
} finally {
pool.shutdownNow();
assertTrue(pool.awaitTermination(2 * timeout, SECONDS));
}
}
}

View file

@ -0,0 +1,166 @@
/*
* Copyright (c) 2024, 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 8350704
* @summary Test behaviors with Signature attribute with any absent
* class or interface (the string is of valid format)
* @library /test/lib
* @modules java.base/jdk.internal.classfile.components
* @compile MalformedSignatureTest.java
* @comment reuses Sample classes from MalformedSignatureTest
* @run junit TypeNotPresentInSignatureTest
*/
import java.lang.classfile.ClassFile;
import java.lang.classfile.ClassTransform;
import java.lang.classfile.attribute.ExceptionsAttribute;
import java.lang.constant.ClassDesc;
import java.lang.reflect.TypeVariable;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import jdk.internal.classfile.components.ClassRemapper;
import jdk.test.lib.ByteCodeLoader;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class TypeNotPresentInSignatureTest {
static Class<?> sampleClass, sampleRecord;
@BeforeAll
static void setup() throws Exception {
var compiledDir = Path.of(System.getProperty("test.classes"));
var cf = ClassFile.of();
// Transforms all references to RuntimeException to an absent class or
// interface does.not.Exist. The signature string format is still valid.
var reDesc = ClassDesc.of("java.lang.RuntimeException");
var fix = ClassRemapper.of(Map.of(reDesc, ClassDesc.of("does.not.Exist")));
var f2 = ClassTransform.transformingMethods((mb, me) -> {
if (me instanceof ExceptionsAttribute) {
mb.with(ExceptionsAttribute.ofSymbols(reDesc));
} else {
mb.with(me);
}
});
var plainBytes = cf.transformClass(cf.parse(compiledDir.resolve("SampleClass.class")), fix);
plainBytes = cf.transformClass(cf.parse(plainBytes), f2);
sampleClass = ByteCodeLoader.load("SampleClass", plainBytes);
var recordBytes = cf.transformClass(cf.parse(compiledDir.resolve("SampleRecord.class")), fix);
recordBytes = cf.transformClass(cf.parse(recordBytes), f2);
sampleRecord = ByteCodeLoader.load("SampleRecord", recordBytes);
}
/**
* Ensures the reflective generic inspection of a Class with missing class
* or interface throws TypeNotPresentException while the non-generic
* inspection is fine.
*/
@Test
void testClass() {
assertEquals(ArrayList.class, sampleClass.getSuperclass());
assertArrayEquals(new Class<?>[] {Predicate.class}, sampleClass.getInterfaces());
var ex = assertThrows(TypeNotPresentException.class, sampleClass::getGenericSuperclass);
assertEquals("does.not.Exist", ex.typeName());
ex = assertThrows(TypeNotPresentException.class, sampleClass::getGenericInterfaces);
assertEquals("does.not.Exist", ex.typeName());
}
/**
* Ensures the reflective generic inspection of a Field with missing class
* or interface throws TypeNotPresentException while the non-generic
* inspection is fine.
*/
@Test
void testField() throws ReflectiveOperationException {
var field = sampleClass.getDeclaredField("field");
assertEquals(Optional.class, field.getType());
var ex = assertThrows(TypeNotPresentException.class, field::getGenericType);
assertEquals("does.not.Exist", ex.typeName());
}
/**
* Ensures the reflective generic inspection of a Constructor with missing class
* or interface throws TypeNotPresentException while the non-generic
* inspection is fine.
*/
@Test
void testConstructor() throws ReflectiveOperationException {
var constructor = sampleClass.getDeclaredConstructor(Optional.class);
assertArrayEquals(new Class<?>[] {Optional.class}, constructor.getParameterTypes());
assertArrayEquals(new Class<?>[] {RuntimeException.class}, constructor.getExceptionTypes());
var ex = assertThrows(TypeNotPresentException.class, constructor::getGenericParameterTypes);
assertEquals("does.not.Exist", ex.typeName());
var typeVar = (TypeVariable<?>) constructor.getGenericExceptionTypes()[0];
ex = assertThrows(TypeNotPresentException.class, typeVar::getBounds);
assertEquals("does.not.Exist", ex.typeName());
}
/**
* Ensures the reflective generic inspection of a Method with missing class
* or interface throws TypeNotPresentException while the non-generic
* inspection is fine.
*/
@Test
void testMethod() throws ReflectiveOperationException {
var method = sampleClass.getDeclaredMethod("method", Optional.class);
assertEquals(Optional.class, method.getReturnType());
assertArrayEquals(new Class<?>[] {Optional.class}, method.getParameterTypes());
assertArrayEquals(new Class<?>[] {RuntimeException.class}, method.getExceptionTypes());
var ex = assertThrows(TypeNotPresentException.class, method::getGenericReturnType);
assertEquals("does.not.Exist", ex.typeName());
ex = assertThrows(TypeNotPresentException.class, method::getGenericParameterTypes);
assertEquals("does.not.Exist", ex.typeName());
var typeVar = (TypeVariable<?>) method.getGenericExceptionTypes()[0];
ex = assertThrows(TypeNotPresentException.class, typeVar::getBounds);
assertEquals("does.not.Exist", ex.typeName());
}
/**
* Ensures the reflective generic inspection of a RecordComponent with missing class
* or interface throws TypeNotPresentException while the non-generic
* inspection is fine.
*/
@Test
void testRecordComponent() {
var rcs = sampleRecord.getRecordComponents();
assertNotNull(rcs);
assertEquals(1, rcs.length);
var rc = rcs[0];
assertNotNull(rc);
assertEquals(Optional.class, rc.getType());
assertEquals("Ljava/util/Optional<Ldoes/not/Exist;>;", rc.getGenericSignature());
var ex = assertThrows(TypeNotPresentException.class, rc::getGenericType);
assertEquals("does.not.Exist", ex.typeName());
}
}

View file

@ -0,0 +1,45 @@
/*
* 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 4981727
* @summary
*/
import java.io.PrintStream;
public class exceptionCauseTest {
public static void main(String args[]) {
Throwable cause = new Throwable("because");
Throwable par = new Throwable(cause);
TypeNotPresentException cnp = new TypeNotPresentException("test", par);
try {
throw cnp;
} catch (TypeNotPresentException e) {
if (par != e.getCause() )
throw new RuntimeException("Unexpected value of cause.");
}
}
}

View file

@ -0,0 +1,64 @@
/*
* 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 4979440
* @summary Test for signature parsing corner case
*/
import java.lang.reflect.*;
import java.lang.annotation.*;
/*
* Make sure:
* 1. getAnnotation can be called directly
* 2. getAnnotation can be called reflectively
* 3. generic information methods on the Method object for
* getAnnotation can be called
*/
public class getAnnotationTest {
public static void main (String[] args) throws Throwable {
// Base level
Class c = Class.forName("java.lang.annotation.Retention");
Annotation result = c.getAnnotation(Retention.class);
// System.out.println("Base result:" + result);
// Meta level, invoke Class.getAnnotation reflectively...
Class meta_c = c.getClass();
Method meta_getAnnotation = meta_c.getMethod("getAnnotation",
(Retention.class).getClass());
Object meta_result = meta_getAnnotation.invoke(c, Retention.class);
// System.out.println("Meta result:" + meta_result);
if (!meta_result.equals(result)) {
throw new RuntimeException("Base and meta results are not equal.");
}
meta_getAnnotation.getGenericExceptionTypes();
meta_getAnnotation.getGenericParameterTypes();
meta_getAnnotation.getGenericReturnType();
}
}