8376277: Migrate java/lang/reflect tests away from TestNG

Reviewed-by: alanb
This commit is contained in:
Chen Liang 2026-01-27 14:51:04 +00:00
parent 64b0ae6be8
commit bbb4b0d498
28 changed files with 511 additions and 706 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 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
@ -21,11 +21,11 @@
* questions.
*/
/**
/*
* @test
* @build CanAccessTest
* @modules java.base/jdk.internal.misc:+open
* @run testng/othervm CanAccessTest
* @run junit/othervm CanAccessTest
* @summary Test AccessibleObject::canAccess method
*/
@ -34,31 +34,29 @@ import java.lang.reflect.Method;
import java.security.SecureClassLoader;
import jdk.internal.misc.Unsafe;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
@Test
public class CanAccessTest {
private static Unsafe INSTANCE = Unsafe.getUnsafe();
/**
* null object parameter for Constructor
*/
@Test
public void testConstructor() throws Exception {
Constructor<?> ctor = Unsafe.class.getDeclaredConstructor();
assertFalse(ctor.canAccess(null));
assertTrue(ctor.trySetAccessible());
try {
// non-null object parameter
ctor.canAccess(INSTANCE);
assertTrue(false);
} catch (IllegalArgumentException expected) {}
assertThrows(IllegalArgumentException.class, () -> ctor.canAccess(INSTANCE));
}
/**
* Test protected constructors
*/
@Test
public void testProtectedConstructor() throws Exception {
TestLoader.testProtectedConstructorNonOpenedPackage();
@ -69,21 +67,20 @@ public class CanAccessTest {
/**
* null object parameter for static members
*/
@Test
public void testStaticMember() throws Exception {
Method m = Unsafe.class.getDeclaredMethod("throwIllegalAccessError");
assertFalse(m.canAccess(null));
assertTrue(m.trySetAccessible());
try {
// non-null object parameter
m.canAccess(INSTANCE);
assertTrue(false);
} catch (IllegalArgumentException expected) { }
assertThrows(IllegalArgumentException.class, () -> m.canAccess(INSTANCE));
}
/**
* Test protected static
*/
@Test
public void testProtectedStatic() throws Exception {
Method m = TestLoader.testProtectedStatic();
assertFalse(m.canAccess(null));
@ -93,28 +90,24 @@ public class CanAccessTest {
* the specified object must be an instance of the declaring class
* for instance members
*/
@Test
public void testInstanceMethod() throws Exception {
Method m = Unsafe.class.getDeclaredMethod("allocateMemory0", long.class);
assertFalse(m.canAccess(INSTANCE));
try {
m.canAccess(null);
assertTrue(false);
} catch (IllegalArgumentException expected) { }
assertThrows(IllegalArgumentException.class, () -> m.canAccess(null));
}
/**
* the specified object must be an instance of the declaring class
* for instance members
*/
@Test
public void testInvalidInstanceObject() throws Exception {
Class<?> clazz = Class.forName("sun.security.x509.X500Name");
Method m = clazz.getDeclaredMethod("size");
try {
m.canAccess(INSTANCE);
assertTrue(false);
} catch (IllegalArgumentException expected) { }
assertThrows(IllegalArgumentException.class, () -> m.canAccess(INSTANCE));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 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
@ -21,12 +21,12 @@
* questions.
*/
/**
/*
* @test
* @build ModuleSetAccessibleTest
* @modules java.base/java.lang:open
* java.base/jdk.internal.misc:+open
* @run testng/othervm ModuleSetAccessibleTest
* @run junit/othervm ModuleSetAccessibleTest
* @summary Test java.lang.reflect.AccessibleObject with modules
*/
@ -40,22 +40,19 @@ import java.security.ProtectionDomain;
import jdk.internal.misc.Unsafe;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
@Test
public class ModuleSetAccessibleTest {
/**
* Invoke a private constructor on a public class in an exported package
*/
@Test
public void testPrivateConstructorInExportedPackage() throws Exception {
Constructor<?> ctor = Unsafe.class.getDeclaredConstructor();
try {
ctor.newInstance();
assertTrue(false);
} catch (IllegalAccessException expected) { }
assertThrows(IllegalAccessException.class, () -> ctor.newInstance());
ctor.setAccessible(true);
Unsafe unsafe = (Unsafe) ctor.newInstance();
@ -65,34 +62,26 @@ public class ModuleSetAccessibleTest {
/**
* Invoke a private method on a public class in an exported package
*/
@Test
public void testPrivateMethodInExportedPackage() throws Exception {
Method m = Unsafe.class.getDeclaredMethod("throwIllegalAccessError");
try {
m.invoke(null);
assertTrue(false);
} catch (IllegalAccessException expected) { }
assertThrows(IllegalAccessException.class, () -> m.invoke(null));
m.setAccessible(true);
try {
m.invoke(null);
assertTrue(false);
} catch (InvocationTargetException e) {
InvocationTargetException e = assertThrows(InvocationTargetException.class, () ->
m.invoke(null));
// thrown by throwIllegalAccessError
assertTrue(e.getCause() instanceof IllegalAccessError);
}
assertInstanceOf(IllegalAccessError.class, e.getCause());
}
/**
* Access a private field in a public class that is an exported package
*/
@Test
public void testPrivateFieldInExportedPackage() throws Exception {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
try {
f.get(null);
assertTrue(false);
} catch (IllegalAccessException expected) { }
assertThrows(IllegalAccessException.class, () -> f.get(null));
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
@ -102,19 +91,14 @@ public class ModuleSetAccessibleTest {
/**
* Invoke a public constructor on a public class in a non-exported package
*/
@Test
public void testPublicConstructorInNonExportedPackage() throws Exception {
Class<?> clazz = Class.forName("sun.security.x509.X500Name");
Constructor<?> ctor = clazz.getConstructor(String.class);
try {
ctor.newInstance("cn=duke");
assertTrue(false);
} catch (IllegalAccessException expected) { }
assertThrows(IllegalAccessException.class, () -> ctor.newInstance("cn=duke"));
try {
ctor.setAccessible(true);
assertTrue(false);
} catch (InaccessibleObjectException expected) { }
assertThrows(InaccessibleObjectException.class, () -> ctor.setAccessible(true));
ctor.setAccessible(false); // should succeed
}
@ -123,19 +107,14 @@ public class ModuleSetAccessibleTest {
/**
* Access a public field in a public class that in a non-exported package
*/
@Test
public void testPublicFieldInNonExportedPackage() throws Exception {
Class<?> clazz = Class.forName("sun.security.x509.X500Name");
Field f = clazz.getField("SERIALNUMBER_OID");
try {
f.get(null);
assertTrue(false);
} catch (IllegalAccessException expected) { }
assertThrows(IllegalAccessException.class, () -> f.get(null));
try {
f.setAccessible(true);
assertTrue(false);
} catch (InaccessibleObjectException expected) { }
assertThrows(InaccessibleObjectException.class, () -> f.setAccessible(true));
f.setAccessible(false); // should succeed
}
@ -144,6 +123,7 @@ public class ModuleSetAccessibleTest {
/**
* Test that the Class constructor cannot be make accessible.
*/
@Test
public void testJavaLangClass() throws Exception {
// non-public constructor
@ -152,15 +132,8 @@ public class ModuleSetAccessibleTest {
ProtectionDomain.class, boolean.class, char.class);
AccessibleObject[] ctors = { ctor };
try {
ctor.setAccessible(true);
assertTrue(false);
} catch (SecurityException expected) { }
try {
AccessibleObject.setAccessible(ctors, true);
assertTrue(false);
} catch (SecurityException expected) { }
assertThrows(SecurityException.class, () -> ctor.setAccessible(true));
assertThrows(SecurityException.class, () -> AccessibleObject.setAccessible(ctors, true));
// should succeed
ctor.setAccessible(false);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 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
@ -21,14 +21,14 @@
* questions.
*/
/**
/*
* @test
* @build TrySetAccessibleTest
* @modules java.base/java.lang:open
* java.base/jdk.internal.module
* java.base/jdk.internal.perf
* java.base/jdk.internal.misc:+open
* @run testng/othervm TrySetAccessibleTest
* @run junit/othervm TrySetAccessibleTest
* @summary Test AccessibleObject::trySetAccessible method
*/
@ -43,21 +43,18 @@ import jdk.internal.module.ModulePath;
import jdk.internal.perf.Perf;
import java.security.ProtectionDomain;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
@Test
public class TrySetAccessibleTest {
/**
* Invoke a private constructor on a public class in an exported package
*/
@Test
public void testPrivateConstructorInExportedPackage() throws Exception {
Constructor<?> ctor = Perf.class.getDeclaredConstructor();
try {
ctor.newInstance();
assertTrue(false);
} catch (IllegalAccessException expected) { }
assertThrows(IllegalAccessException.class, () -> ctor.newInstance());
assertFalse(ctor.trySetAccessible());
assertFalse(ctor.canAccess(null));
@ -66,13 +63,11 @@ public class TrySetAccessibleTest {
/**
* Invoke a private constructor on a public class in an open package
*/
@Test
public void testPrivateConstructorInOpenedPackage() throws Exception {
Constructor<?> ctor = Unsafe.class.getDeclaredConstructor();
try {
ctor.newInstance();
assertTrue(false);
} catch (IllegalAccessException expected) { }
assertThrows(IllegalAccessException.class, () -> ctor.newInstance());
assertTrue(ctor.trySetAccessible());
assertTrue(ctor.canAccess(null));
@ -82,12 +77,10 @@ public class TrySetAccessibleTest {
/**
* Invoke a private method on a public class in an exported package
*/
@Test
public void testPrivateMethodInExportedPackage() throws Exception {
Method m = ModulePath.class.getDeclaredMethod("packageName", String.class);
try {
m.invoke(null);
assertTrue(false);
} catch (IllegalAccessException expected) { }
assertThrows(IllegalAccessException.class, () -> m.invoke(null));
assertFalse(m.trySetAccessible());
assertFalse(m.canAccess(null));
@ -97,54 +90,42 @@ public class TrySetAccessibleTest {
/**
* Invoke a private method on a public class in an open package
*/
@Test
public void testPrivateMethodInOpenedPackage() throws Exception {
Method m = Unsafe.class.getDeclaredMethod("throwIllegalAccessError");
assertFalse(m.canAccess(null));
try {
m.invoke(null);
assertTrue(false);
} catch (IllegalAccessException expected) { }
assertThrows(IllegalAccessException.class, () -> m.invoke(null));
assertTrue(m.trySetAccessible());
assertTrue(m.canAccess(null));
try {
m.invoke(null);
assertTrue(false);
} catch (InvocationTargetException e) {
// thrown by throwIllegalAccessError
assertTrue(e.getCause() instanceof IllegalAccessError);
}
InvocationTargetException e = assertThrows(InvocationTargetException.class, () ->
m.invoke(null));
assertInstanceOf(IllegalAccessError.class, e.getCause());
}
/**
* Invoke a private method on a public class in an exported package
*/
@Test
public void testPrivateFieldInExportedPackage() throws Exception {
Field f = Perf.class.getDeclaredField("instance");
try {
f.get(null);
assertTrue(false);
} catch (IllegalAccessException expected) { }
assertThrows(IllegalAccessException.class, () -> f.get(null));
assertFalse(f.trySetAccessible());
assertFalse(f.canAccess(null));
try {
f.get(null);
assertTrue(false);
} catch (IllegalAccessException expected) {}
assertThrows(IllegalAccessException.class, () -> f.get(null));
}
/**
* Access a private field in a public class that is an exported package
*/
@Test
public void testPrivateFieldInOpenedPackage() throws Exception {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
try {
f.get(null);
assertTrue(false);
} catch (IllegalAccessException expected) { }
assertThrows(IllegalAccessException.class, () -> f.get(null));
assertTrue(f.trySetAccessible());
assertTrue(f.canAccess(null));
@ -155,32 +136,29 @@ public class TrySetAccessibleTest {
/**
* Invoke a public constructor on a public class in a non-exported package
*/
@Test
public void testPublicConstructorInNonExportedPackage() throws Exception {
Class<?> clazz = Class.forName("sun.security.x509.X500Name");
Constructor<?> ctor = clazz.getConstructor(String.class);
try {
ctor.newInstance("cn=duke");
assertTrue(false);
} catch (IllegalAccessException expected) { }
assertThrows(IllegalAccessException.class, () -> ctor.newInstance("cn=duke"));
assertFalse(ctor.trySetAccessible());
assertFalse(ctor.canAccess(null));
assertTrue(ctor.trySetAccessible() == ctor.isAccessible());
assertFalse(ctor.trySetAccessible());
assertFalse(ctor.isAccessible()); // should match trySetAccessible
}
/**
* Access a public field in a public class that in a non-exported package
*/
@Test
public void testPublicFieldInNonExportedPackage() throws Exception {
Class<?> clazz = Class.forName("sun.security.x509.X500Name");
Field f = clazz.getField("SERIALNUMBER_OID");
try {
f.get(null);
assertTrue(false);
} catch (IllegalAccessException expected) { }
assertThrows(IllegalAccessException.class, () -> f.get(null));
assertFalse(f.trySetAccessible());
assertFalse(f.canAccess(null));
@ -190,6 +168,7 @@ public class TrySetAccessibleTest {
/**
* Test that the Class constructor cannot be make accessible.
*/
@Test
public void testJavaLangClass() throws Exception {
// non-public constructor

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* 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
@ -23,9 +23,11 @@
/*
* @test
* @run testng/othervm ChainedReflection
* @run junit/othervm ChainedReflection
* @summary Test Method::invoke and Constructor::newInstance chained calls that
* should wrap NPE in InvocationTargetException properly
* @comment This test is not using assertThrows given lambdas may affect the
* exception stack trace and therefore test anticipations
*/
import java.lang.reflect.Constructor;
@ -33,12 +35,15 @@ import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.util.Optional;
import org.testng.annotations.Test;
import org.junit.jupiter.api.Test;
public class ChainedReflection {
public ChainedReflection() {}
ChainedReflection(Void dummy) throws ReflectiveOperationException {
// This inner class is declared with a constructor that ctorCallMethodInvoke
// reflects on. Such a constructor cannot be declared in ChainedReflection
// because JUnit does not allow a test class to declare multiple constructors.
class Inner {
Inner() throws ReflectiveOperationException {
Method m = ChainedReflection.class.getMethod("throwNPE");
try {
m.invoke(null);
@ -53,6 +58,7 @@ public class ChainedReflection {
throw new RuntimeException("Test failed (Unexpected exception)", t);
}
}
}
public static void throwNPE() {
throw new NullPointerException();
@ -105,9 +111,9 @@ public class ChainedReflection {
*/
@Test
public void ctorCallMethodInvoke() throws ReflectiveOperationException {
Constructor<?> ctor = ChainedReflection.class.getDeclaredConstructor(Void.class);
Constructor<?> ctor = ChainedReflection.Inner.class.getDeclaredConstructor(ChainedReflection.class);
try {
ctor.newInstance((Void)null);
ctor.newInstance(this);
} catch (InvocationTargetException e) {
Throwable t = e.getTargetException();
if (!(t instanceof NullPointerException)) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 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
@ -26,7 +26,7 @@
* @bug 8029674
* @summary Verify that the right interface methods are returned by
* Class.getMethod() and Class.getMethods()
* @run testng FilterNotMostSpecific
* @run junit FilterNotMostSpecific
*/
import java.lang.reflect.*;
@ -39,14 +39,14 @@ import java.util.HashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class FilterNotMostSpecific {
@Test(dataProvider="getCases")
@ParameterizedTest
@MethodSource("getCases")
public void testGetMethod(Class<?> iface) {
boolean match = false;
MethodDesc[] expectedMethods = iface.getAnnotationsByType(MethodDesc.class);
@ -67,7 +67,8 @@ public class FilterNotMostSpecific {
assert(match);
}
@Test(dataProvider="getCases")
@ParameterizedTest
@MethodSource("getCases")
public void testGetMethods(Class<?> iface) {
List<Method> foundMethods = filterObjectMethods(iface.getMethods());
MethodDesc[] expectedMethods = iface.getAnnotationsByType(MethodDesc.class);
@ -84,7 +85,7 @@ public class FilterNotMostSpecific {
fail("On: "+ iface +"\nDid not find " + toMethodString(expected) +
" among " + foundMethods);
}
assertEquals(foundMethods.size(), expectedMethods.length,
assertEquals(expectedMethods.length, foundMethods.size(),
"\non: " + iface +
"\nexpected: " + toMethodStrings(expectedMethods) +
"\nfound: " + foundMethods + "\n");
@ -565,8 +566,7 @@ public class FilterNotMostSpecific {
@MethodDesc(name="m", declaringClass=F.class, isGetMethodReturn=true)
abstract class H extends G implements F {}
@DataProvider
public Object[][] getCases() { return CASES; }
public static Object[][] getCases() { return CASES; }
public static final Class<?>[][] CASES = {
{ K1.class },
{ K1M.class },

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 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
@ -27,7 +27,7 @@
* in interfaces and/or in inheritance
* @bug 7184826
* @build helper.Mod helper.Declared DefaultStaticTestData
* @run testng DefaultStaticInvokeTest
* @run junit DefaultStaticInvokeTest
* @author Yong Lu
*/
@ -40,23 +40,19 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.fail;
import org.testng.annotations.Test;
import static helper.Mod.*;
import static helper.Declared.*;
import helper.Mod;
import static org.junit.jupiter.api.Assertions.*;
import helper.Mod;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class DefaultStaticInvokeTest {
// getMethods(): Make sure getMethods returns the expected methods.
@Test(dataProvider = "testCasesAll",
dataProviderClass = DefaultStaticTestData.class)
@ParameterizedTest
@MethodSource({"DefaultStaticTestData#testClasses", "DefaultStaticTestData#testInterfaces"})
public void testGetMethods(String testTarget, Object param)
throws Exception {
testMethods(ALL_METHODS, testTarget, param);
@ -64,8 +60,8 @@ public class DefaultStaticInvokeTest {
// getDeclaredMethods(): Make sure getDeclaredMethods returns the expected methods.
@Test(dataProvider = "testCasesAll",
dataProviderClass = DefaultStaticTestData.class)
@ParameterizedTest
@MethodSource({"DefaultStaticTestData#testClasses", "DefaultStaticTestData#testInterfaces"})
public void testGetDeclaredMethods(String testTarget, Object param)
throws Exception {
testMethods(DECLARED_ONLY, testTarget, param);
@ -73,8 +69,8 @@ public class DefaultStaticInvokeTest {
// getMethod(): Make sure that getMethod finds all methods it should find.
@Test(dataProvider = "testCasesAll",
dataProviderClass = DefaultStaticTestData.class)
@ParameterizedTest
@MethodSource({"DefaultStaticTestData#testClasses", "DefaultStaticTestData#testInterfaces"})
public void testGetMethod(String testTarget, Object param)
throws Exception {
@ -91,8 +87,8 @@ public class DefaultStaticInvokeTest {
// getMethod(): Make sure that getMethod does *not* find certain methods.
@Test(dataProvider = "testCasesAll",
dataProviderClass = DefaultStaticTestData.class)
@ParameterizedTest
@MethodSource({"DefaultStaticTestData#testClasses", "DefaultStaticTestData#testInterfaces"})
public void testGetMethodSuperInterfaces(String testTarget, Object param)
throws Exception {
@ -124,8 +120,8 @@ public class DefaultStaticInvokeTest {
// Method.invoke(): Make sure Method.invoke returns the expected value.
@Test(dataProvider = "testCasesAll",
dataProviderClass = DefaultStaticTestData.class)
@ParameterizedTest
@MethodSource({"DefaultStaticTestData#testClasses", "DefaultStaticTestData#testInterfaces"})
public void testMethodInvoke(String testTarget, Object param)
throws Exception {
Class<?> typeUnderTest = Class.forName(testTarget);
@ -141,8 +137,8 @@ public class DefaultStaticInvokeTest {
// MethodHandle.invoke(): Make sure MethodHandle.invoke returns the expected value.
@Test(dataProvider = "testCasesAll",
dataProviderClass = DefaultStaticTestData.class)
@ParameterizedTest
@MethodSource({"DefaultStaticTestData#testClasses", "DefaultStaticTestData#testInterfaces"})
public void testMethodHandleInvoke(String testTarget, Object param)
throws Throwable {
Class<?> typeUnderTest = Class.forName(testTarget);
@ -169,14 +165,14 @@ public class DefaultStaticInvokeTest {
: (String) methodHandle.invoke(typeUnderTest.newInstance(), param);
}
assertEquals(result, expectedReturn);
assertEquals(expectedReturn, result);
}
}
// Lookup.findStatic / .findVirtual: Make sure IllegalAccessException is thrown as expected.
@Test(dataProvider = "testClasses",
dataProviderClass = DefaultStaticTestData.class)
@ParameterizedTest
@MethodSource("DefaultStaticTestData#testClasses")
public void testIAE(String testTarget, Object param)
throws ClassNotFoundException {
@ -189,14 +185,8 @@ public class DefaultStaticInvokeTest {
if (mod != STATIC && typeUnderTest.isInterface()) {
continue;
}
Exception caught = null;
try {
getTestMH(typeUnderTest, mName, param, true);
} catch (Exception e) {
caught = e;
}
assertNotNull(caught);
assertEquals(caught.getClass(), IllegalAccessException.class);
assertThrowsExactly(IllegalAccessException.class, () ->
getTestMH(typeUnderTest, mName, param, true));
}
}
@ -254,7 +244,7 @@ public class DefaultStaticInvokeTest {
}
}
assertEquals(myMethods.size(), expectedMethods.length);
assertEquals(expectedMethods.length, myMethods.size());
for (MethodDesc toTest : expectedMethods) {
@ -284,16 +274,15 @@ public class DefaultStaticInvokeTest {
assertFalse(method.isDefault());
// Test invoke it
assertEquals(tryInvoke(method, null, param), expectedReturn);
assertEquals(expectedReturn, tryInvoke(method, null, param));
break;
case DEFAULT:
// if typeUnderTest is a class then instantiate and invoke
if (!typeUnderTest.isInterface()) {
assertEquals(tryInvoke(
assertEquals(expectedReturn, tryInvoke(
method,
typeUnderTest,
param),
expectedReturn);
param));
}
//assert candidate is default
@ -302,11 +291,10 @@ public class DefaultStaticInvokeTest {
break;
case REGULAR:
// if typeUnderTest must be a class
assertEquals(tryInvoke(
assertEquals(expectedReturn, tryInvoke(
method,
typeUnderTest,
param),
expectedReturn);
param));
//assert candidate is neither default nor static
assertFalse(Modifier.isStatic(method.getModifiers()));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 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
@ -27,12 +27,10 @@
* @author Yong Lu
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.testng.annotations.DataProvider;
import org.testng.collections.Lists;
import static helper.Mod.*;
import static helper.Declared.*;
import helper.Mod;
@ -379,7 +377,6 @@ public class DefaultStaticTestData {
* data is the name of the class under test Second data used in test as the
* arguments used for the method call.
*/
@DataProvider
static Object[][] testClasses() {
return new Object[][]{
{"TestClass1", null},
@ -408,7 +405,6 @@ public class DefaultStaticTestData {
* data is the name of the interface under test Second data used in test as
* the arguments used for the method call.
*/
@DataProvider
static Object[][] testInterfaces() {
return new Object[][]{
{"TestIF1", null},
@ -438,12 +434,4 @@ public class DefaultStaticTestData {
{"TestIF21", null},
};
}
@DataProvider
static Object[][] testCasesAll() {
List<Object[]> result = Lists.newArrayList();
result.addAll(Arrays.asList(testClasses()));
result.addAll(Arrays.asList(testInterfaces()));
return result.toArray(new Object[result.size()][]);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
* 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
@ -21,20 +21,20 @@
* questions.
*/
/**
/*
* @test
* @bug 8277451
* @summary Test exception thrown due to bad receiver and bad value on
* Field with and without setAccessible(true)
* @run testng/othervm --enable-final-field-mutation=ALL-UNNAMED NegativeTest
* @run junit/othervm --enable-final-field-mutation=ALL-UNNAMED NegativeTest
*/
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class NegativeTest {
static class Fields {
@ -167,8 +167,7 @@ public class NegativeTest {
}
}
@DataProvider(name = "instanceFields")
private Object[][] instanceFields() {
private static Object[][] instanceFields() {
return new Object[][]{
new Object[]{i_field},
new Object[]{c_field},
@ -217,7 +216,8 @@ public class NegativeTest {
* IllegalArgumentException is thrown if the receiver is of
* a bad type. NullPointerException is thrown if the receiver is null.
*/
@Test(dataProvider = "instanceFields")
@ParameterizedTest
@MethodSource("instanceFields")
public void testReceiver(Field f) throws ReflectiveOperationException {
f.get(INSTANCE); // good receiver
@ -231,15 +231,10 @@ public class NegativeTest {
private void testBadReceiver(Field f) throws ReflectiveOperationException {
assertFalse(Modifier.isStatic(f.getModifiers())); // instance field
Object badObj = new NegativeTest();
try {
f.get(badObj);
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
assertThrows(IllegalArgumentException.class, () -> f.get(badObj));
Class<?> fType = f.getType();
if (fType.isPrimitive()) {
try {
assertThrows(IllegalArgumentException.class, () -> {
switch (fType.descriptorString()) {
case "B" -> f.getByte(badObj);
case "C" -> f.getChar(badObj);
@ -250,10 +245,7 @@ public class NegativeTest {
case "S" -> f.getShort(badObj);
case "Z" -> f.getBoolean(badObj);
}
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
});
}
}
@ -262,16 +254,11 @@ public class NegativeTest {
*/
private void testNullReceiver(Field f) throws ReflectiveOperationException {
assertFalse(Modifier.isStatic(f.getModifiers())); // instance field
try {
f.get(null);
fail("expected NullPointerException");
} catch (NullPointerException e) {
// expected
}
assertThrows(NullPointerException.class, () -> f.get(null));
Class<?> fType = f.getType();
if (fType.isPrimitive()) {
try {
assertThrows(NullPointerException.class, () -> {
switch (fType.descriptorString()) {
case "B" -> f.getByte(null);
case "C" -> f.getChar(null);
@ -282,15 +269,11 @@ public class NegativeTest {
case "S" -> f.getShort(null);
case "Z" -> f.getBoolean(null);
}
fail("expected NullPointerException");
} catch (NullPointerException e) {
// expected
}
});
}
}
@DataProvider(name = "writeableFields")
private Object[][] writeableFields() {
private static Object[][] writeableFields() {
Fields obj = new Fields();
return new Object[][]{
// instance fields with and without setAccessible(true)
@ -352,7 +335,8 @@ public class NegativeTest {
* NullPointerException is thrown if the receiver of an instance field is null.
* The receiver is checked
*/
@Test(dataProvider = "writeableFields")
@ParameterizedTest
@MethodSource("writeableFields")
public void testSetValue(Field f, Object obj, Object value) throws IllegalAccessException {
f.set(obj, value);
Class<?> fType = f.getType();
@ -369,25 +353,14 @@ public class NegativeTest {
}
// test null value only if it's primitive type
try {
f.set(obj, null);
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
assertThrows(IllegalArgumentException.class, () -> f.set(obj, null));
}
Object badValue = new NegativeTest();
try {
f.set(obj, badValue);
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
assertThrows(IllegalArgumentException.class, () -> f.set(obj, badValue));
}
@DataProvider(name = "readOnlyFinalFields")
private Object[][] readOnlyFinalFields() {
private static Object[][] readOnlyFinalFields() {
Object obj = INSTANCE;
return new Object[][]{
// instance final fields
@ -427,19 +400,15 @@ public class NegativeTest {
* IllegalAccessException is thrown regardless of whether the value
* is of a bad type or not.
*/
@Test(dataProvider = "readOnlyFinalFields")
@ParameterizedTest
@MethodSource("readOnlyFinalFields")
public void testSetValueOnFinalField(Field f, Object obj, Object value) {
assertTrue(Modifier.isFinal(f.getModifiers()));
try {
f.set(obj, value);
fail("expected IllegalAccessException");
} catch (IllegalAccessException e) {
// expected
}
assertThrows(IllegalAccessException.class, () -> f.set(obj, value));
Class<?> fType = f.getType();
if (fType.isPrimitive()) {
try {
assertThrows(IllegalAccessException.class, () -> {
switch (fType.descriptorString()) {
case "B" -> f.setByte(obj, ((Byte)value).byteValue());
case "C" -> f.setChar(obj, ((Character)value).charValue());
@ -450,33 +419,17 @@ public class NegativeTest {
case "S" -> f.setShort(obj, ((Short)value).shortValue());
case "Z" -> f.setBoolean(obj, ((Boolean)value).booleanValue());
}
fail("expected IllegalAccessException");
} catch (IllegalAccessException e) {
// expected
}
});
// test null value only if it's primitive type
try {
f.set(obj, null);
fail("expected IllegalAccessException");
} catch (IllegalAccessException e) {
// expected
}
assertThrows(IllegalAccessException.class, () -> f.set(obj, null));
}
Object badValue = new NegativeTest();
try {
f.set(obj, badValue);
fail("expected IllegalAccessException");
} catch (IllegalAccessException e) {
// expected
}
assertThrows(IllegalAccessException.class, () -> f.set(obj, badValue));
}
@DataProvider(name = "finalInstanceFields")
private Object[][] finalInstanceFields() {
private static Object[][] finalInstanceFields() {
return new Object[][]{
new Object[]{fi_field, Integer.valueOf(10)},
new Object[]{fc_field, Character.valueOf('c')},
@ -497,54 +450,27 @@ public class NegativeTest {
* The receiver is checked before the access check is performed and
* also before the value is checked.
*/
@Test(dataProvider = "finalInstanceFields")
@ParameterizedTest
@MethodSource("finalInstanceFields")
public void testReceiverOnFinalField(Field f, Object value) {
assertTrue(Modifier.isFinal(f.getModifiers()));
Object badReceiver = new NegativeTest();
// set the field with a bad receiver with a good value
try {
f.set(badReceiver, value);
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
} catch (IllegalAccessException e) {
throw new RuntimeException("Expected IllegalArgumentException but got: " + e.getMessage(), e);
}
assertThrows(IllegalArgumentException.class, () -> f.set(badReceiver, value));
// set the field with a bad receiver with a bad value
Object badValue = new NegativeTest();
try {
f.set(badReceiver, badValue);
fail("expected IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
} catch (IllegalAccessException e) {
throw new RuntimeException("Expected IllegalArgumentException but got: " + e.getMessage(), e);
}
assertThrows(IllegalArgumentException.class, () -> f.set(badReceiver, badValue));
// set the field with a null receiver with a good value
try {
f.set(null, value);
fail("expected NullPointerException");
} catch (NullPointerException e) {
// expected
} catch (IllegalAccessException e) {
throw new RuntimeException("Expected NullPointerException but got: " + e.getMessage(), e);
}
assertThrows(NullPointerException.class, () -> f.set(null, value));
// set the field with a null receiver with a bad value
try {
f.set(null, badValue);
fail("expected NullPointerException");
} catch (NullPointerException e) {
// expected
} catch (IllegalAccessException e) {
throw new RuntimeException("Expected NullPointerException but got: " + e.getMessage(), e);
}
assertThrows(NullPointerException.class, () -> f.set(null, badValue));
Class<?> fType = f.getType();
if (fType.isPrimitive()) {
// test bad receiver
try {
assertThrows(IllegalArgumentException.class, () -> {
switch (fType.descriptorString()) {
case "B" -> f.setByte(badReceiver, ((Byte) value).byteValue());
case "C" -> f.setChar(badReceiver, ((Character) value).charValue());
@ -555,12 +481,9 @@ public class NegativeTest {
case "S" -> f.setShort(badReceiver, ((Short) value).shortValue());
case "Z" -> f.setBoolean(badReceiver, ((Boolean) value).booleanValue());
}
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
throw new RuntimeException("Expected IllegalArgumentException but got: " + e.getMessage(), e);
}
});
// test null receiver
try {
assertThrows(NullPointerException.class, () -> {
switch (fType.descriptorString()) {
case "B" -> f.setByte(null, ((Byte) value).byteValue());
case "C" -> f.setChar(null, ((Character) value).charValue());
@ -571,11 +494,7 @@ public class NegativeTest {
case "S" -> f.setShort(null, ((Short) value).shortValue());
case "Z" -> f.setBoolean(null, ((Boolean) value).booleanValue());
}
} catch (NullPointerException e) {
// expected
} catch (IllegalAccessException e) {
throw new RuntimeException("Expected NullPointerException but got: " + e.getMessage(), e);
}
});
}
}
}

View File

@ -21,17 +21,16 @@
* questions.
*/
/**
/*
* @test
* @bug 8062771 8016236
* @summary Test publication of Class objects via a data race
* @run testng ThreadSafety
* @run junit ThreadSafety
*/
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.concurrent.BrokenBarrierException;
@ -43,8 +42,8 @@ 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.testng.Assert.*;
import org.testng.annotations.Test;
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):

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
* 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
@ -25,12 +25,14 @@
* @test
* @bug 8277964
* @summary Test IllegalArgumentException be thrown when an argument is invalid
* @run testng/othervm/timeout=720 IllegalArgumentsTest
* @comment Avoid using framework utilities; this is effectively a runtime test
* sensitive to stack traces
* @run junit/othervm/timeout=720 IllegalArgumentsTest
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.testng.annotations.Test;
import org.junit.jupiter.api.Test;
public class IllegalArgumentsTest {
static class T {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* 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
@ -24,18 +24,16 @@
/*
* @test
* @bug 8271820
* @run testng/othervm MethodArityLimit
* @run junit/othervm MethodArityLimit
* @summary Method exceeds the method handle arity limit (255).
*/
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import org.testng.annotations.Test;
import org.junit.jupiter.api.Test;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
import static org.junit.jupiter.api.Assertions.*;
public class MethodArityLimit {
@Test
@ -74,12 +72,10 @@ public class MethodArityLimit {
106L, 107L, 108L, 109L, 110L, 111L, 112L, 113L, 114L, 115L, 116L, 117L,
118L, 119L, 120L, 121L, 122L, 123L, 124L, 125L, 126L, 127);
assertEquals(resultViaMethod, 127);
assertEquals(127, resultViaMethod);
try {
MethodHandle mh = MethodHandles.lookup().unreflect(m);
fail("should fail in creating the method handle");
} catch (IllegalArgumentException e) {}
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,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* 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
@ -26,7 +26,7 @@
* @bug 8271820 8300924
* @modules java.base/jdk.internal.reflect
* @summary Test compliance of ConstructorAccessor, FieldAccessor, MethodAccessor implementations
* @run testng/othervm --add-exports java.base/jdk.internal.reflect=ALL-UNNAMED -XX:-ShowCodeDetailsInExceptionMessages MethodHandleAccessorsTest
* @run junit/othervm -XX:-ShowCodeDetailsInExceptionMessages MethodHandleAccessorsTest
*/
import jdk.internal.reflect.ConstructorAccessor;
@ -44,8 +44,11 @@ import java.util.Objects;
import java.util.function.IntUnaryOperator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class MethodHandleAccessorsTest {
public static void public_static_V() {}
@ -446,9 +449,7 @@ public class MethodHandleAccessorsTest {
new InvocationTargetException(new IllegalArgumentException("IAE"))
};
@DataProvider(name = "testNoArgMethods")
private Object[][] testNoArgMethods() {
private static Object[][] testNoArgMethods() {
MethodHandleAccessorsTest inst = new MethodHandleAccessorsTest();
Object[] emptyArgs = new Object[]{};
return new Object[][] {
@ -468,8 +469,7 @@ public class MethodHandleAccessorsTest {
};
}
@DataProvider(name = "testOneArgMethods")
private Object[][] testOneArgMethods() {
private static Object[][] testOneArgMethods() {
MethodHandleAccessorsTest inst = new MethodHandleAccessorsTest();
Object wrongInst = new Object();
return new Object[][]{
@ -497,8 +497,7 @@ public class MethodHandleAccessorsTest {
};
}
@DataProvider(name = "testMultiArgMethods")
private Object[][] testMultiArgMethods() {
private static Object[][] testMultiArgMethods() {
MethodHandleAccessorsTest inst = new MethodHandleAccessorsTest();
Class<?>[] params_L3 = new Class<?>[] { Object.class, Object.class, Object.class};
Class<?>[] params_L4 = new Class<?>[] { Object.class, Object.class, Object.class, Object.class};
@ -515,8 +514,7 @@ public class MethodHandleAccessorsTest {
};
}
@DataProvider(name = "testMethodsWithVarargs")
private Object[][] testMethodsWithVarargs() {
private static Object[][] testMethodsWithVarargs() {
Class<?>[] paramTypes = new Class<?>[] { int[].class };
Class<?>[] I_paramTypes = new Class<?>[] { int.class, int[].class };
Class<?>[] L_paramTypes = new Class<?>[] { String.class, String[].class };
@ -533,32 +531,35 @@ public class MethodHandleAccessorsTest {
};
}
@Test(dataProvider = "testNoArgMethods")
@ParameterizedTest
@MethodSource("testNoArgMethods")
public void testNoArgMethod(String methodname, Object target, Object[] args,
Object expectedReturn, Throwable[] expectedExpections) throws Exception {
doTest(MethodHandleAccessorsTest.class.getDeclaredMethod(methodname), target, args, expectedReturn, expectedExpections);
}
@Test(dataProvider = "testOneArgMethods")
@ParameterizedTest
@MethodSource("testOneArgMethods")
public void testOneArgMethod(String methodname, Class<?> paramType, Object target, Object[] args,
Object expectedReturn, Throwable[] expectedExpections) throws Exception {
doTest(MethodHandleAccessorsTest.class.getDeclaredMethod(methodname, paramType), target, args, expectedReturn, expectedExpections);
}
@Test(dataProvider = "testMultiArgMethods")
@ParameterizedTest
@MethodSource("testMultiArgMethods")
public void testMultiArgMethod(String methodname, Class<?>[] paramTypes, Object target, Object[] args,
Object expectedReturn, Throwable[] expectedExpections) throws Exception {
doTest(MethodHandleAccessorsTest.class.getDeclaredMethod(methodname, paramTypes), target, args, expectedReturn, expectedExpections);
}
@Test(dataProvider = "testMethodsWithVarargs")
@ParameterizedTest
@MethodSource("testMethodsWithVarargs")
public void testMethodsWithVarargs(String methodname, Class<?>[] paramTypes, Object target, Object[] args,
Object expectedReturn, Throwable[] expectedExpections) throws Exception {
doTest(MethodHandleAccessorsTest.class.getDeclaredMethod(methodname, paramTypes), target, args, expectedReturn, expectedExpections);
}
@DataProvider(name = "testConstructors")
private Object[][] testConstructors() {
private static Object[][] testConstructors() {
return new Object[][]{
new Object[]{null, new Object[]{}, new Public(), noException},
new Object[]{null, null, new Public(), noException},
@ -584,13 +585,13 @@ public class MethodHandleAccessorsTest {
};
}
@Test(dataProvider = "testConstructors")
@ParameterizedTest
@MethodSource("testConstructors")
public void testPublicConstructors(Class<?>[] paramTypes, Object[] args, Object expectedReturn, Throwable[] expectedExpections) throws Exception {
doTest(Public.class.getDeclaredConstructor(paramTypes), args, expectedReturn, expectedExpections);
}
@DataProvider(name = "testMultiArgConstructors")
private Object[][] testMultiArgConstructors() {
private static Object[][] testMultiArgConstructors() {
Class<?>[] params_L3 = new Class<?>[] { Object.class, Object.class, Object.class};
Class<?>[] params_L4 = new Class<?>[] { Object.class, Object.class, Object.class, Object.class};
Object o = "arg";
@ -602,7 +603,8 @@ public class MethodHandleAccessorsTest {
};
}
@Test(dataProvider = "testMultiArgConstructors")
@ParameterizedTest
@MethodSource("testMultiArgConstructors")
public void testMultiArgConstructors(Class<?>[] paramTypes, Object[] args, Object expectedReturn, Throwable[] expectedExpections) throws Exception {
doTest(Public.class.getDeclaredConstructor(paramTypes), args, expectedReturn, expectedExpections);
}
@ -616,8 +618,7 @@ public class MethodHandleAccessorsTest {
doTest(Abstract.class.getDeclaredConstructor(), null, null, new InstantiationException());
}
@DataProvider(name = "throwException")
private Object[][] throwException() {
private static Object[][] throwException() {
return new Object[][]{
new Object[] {new NullPointerException("NPE"), wrapped_npe},
new Object[] {new IllegalArgumentException("IAE"), wrapped_iae},
@ -629,7 +630,8 @@ public class MethodHandleAccessorsTest {
* Test Method::invoke and Constructor::newInstance to wrap NPE/CCE/IAE
* thrown by the member
*/
@Test(dataProvider = "throwException")
@ParameterizedTest
@MethodSource("throwException")
public void testInvocationTargetException(Throwable ex, Throwable[] expectedExpections) throws Exception {
Object[] args = new Object[] { ex };
// test static method
@ -646,8 +648,7 @@ public class MethodHandleAccessorsTest {
doTest(applyAsIntMethod, intUnaryOp, new Object[]{12}, 12);
}
@DataProvider(name = "readAccess")
private Object[][] readAccess() {
private static Object[][] readAccess() {
String wrongInst = new String();
return new Object[][]{
new Object[]{"i", new Public(100), 100, noException},
@ -657,8 +658,7 @@ public class MethodHandleAccessorsTest {
new Object[]{"b", wrongInst, 0, cannot_get_field},
};
}
@DataProvider(name = "writeAccess")
private Object[][] writeAccess() {
private static Object[][] writeAccess() {
Object o = new Object();
byte b = 1;
return new Object[][]{
@ -673,14 +673,16 @@ public class MethodHandleAccessorsTest {
};
}
@Test(dataProvider = "readAccess")
@ParameterizedTest
@MethodSource("readAccess")
public void testFieldReadAccess(String name, Object target, Object expectedValue, Throwable[] expectedExpections) throws Exception {
Field f = Public.class.getDeclaredField(name);
f.setAccessible(true);
doTest(f, target, expectedValue, expectedExpections);
}
@Test(dataProvider = "writeAccess")
@ParameterizedTest
@MethodSource("writeAccess")
public void testFieldWriteAccess(String name, Object target, Object oldValue, Object newValue, Throwable[] expectedExpections) throws Exception {
Field f = Public.class.getDeclaredField(name);
f.setAccessible(true);
@ -693,8 +695,6 @@ public class MethodHandleAccessorsTest {
Field f = Public.class.getDeclaredField("STATIC_FINAL");
doTest(f, new Public(), 1, noException);
try {
f.setInt(null, 100);
} catch (IllegalAccessException e) { }
assertThrows(IllegalAccessException.class, () -> f.setInt(null, 100));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 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
@ -23,19 +23,19 @@
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
/**
/*
* @test
* @bug 8159746
* @run testng DefaultMethods
* @run junit DefaultMethods
* @summary Basic tests for Proxy::invokeSuper default method
*/
@ -96,15 +96,11 @@ public class DefaultMethods {
}
private static Method findDefaultMethod(Class<?> refc, Method m) {
try {
assertTrue(refc.isInterface());
Method method = refc.getMethod(m.getName(), m.getParameterTypes());
Method method = assertDoesNotThrow(() -> refc.getMethod(m.getName(), m.getParameterTypes()));
assertTrue(method.isDefault());
return method;
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
@Test
@ -115,12 +111,11 @@ public class DefaultMethods {
return InvocationHandler.invokeDefault(o, findDefaultMethod(I2.class, method), params);
});
I1 i1 = (I1) proxy;
assertEquals(i1.m(), 20);
assertEquals(20, i1.m());
}
// a default method is declared in one of the proxy interfaces
@DataProvider(name = "defaultMethods")
private Object[][] defaultMethods() {
private static Object[][] defaultMethods() {
return new Object[][]{
new Object[]{new Class<?>[]{I1.class, I2.class}, true, 10},
new Object[]{new Class<?>[]{I1.class, I3.class}, true, 10},
@ -133,13 +128,14 @@ public class DefaultMethods {
};
}
@Test(dataProvider = "defaultMethods")
@ParameterizedTest
@MethodSource("defaultMethods")
public void testDefaultMethod(Class<?>[] intfs, boolean isDefault, int expected) throws Throwable {
InvocationHandler ih = (proxy, method, params) -> {
System.out.format("invoking %s with parameters: %s%n", method, Arrays.toString(params));
switch (method.getName()) {
case "m":
assertTrue(method.isDefault() == isDefault);
assertEquals(isDefault, method.isDefault());
assertTrue(Arrays.stream(proxy.getClass().getInterfaces())
.anyMatch(intf -> method.getDeclaringClass() == intf),
Arrays.toString(proxy.getClass().getInterfaces()));
@ -156,13 +152,12 @@ public class DefaultMethods {
Object proxy = Proxy.newProxyInstance(DefaultMethods.class.getClassLoader(), intfs, ih);
Method m = proxy.getClass().getMethod("m");
int result = (int)m.invoke(proxy);
assertEquals(result, expected);
assertEquals(expected, result);
}
// a default method may be declared in a proxy interface or
// inherited from a superinterface of a proxy interface
@DataProvider(name = "supers")
private Object[][] supers() {
private static Object[][] supers() {
return new Object[][]{
// invoke "m" implemented in the first proxy interface
// same as the method passed to InvocationHandler::invoke
@ -188,7 +183,8 @@ public class DefaultMethods {
};
}
@Test(dataProvider = "supers")
@ParameterizedTest
@MethodSource("supers")
public void testSuper(Class<?>[] intfs, Class<?> proxyInterface, int expected) throws Throwable {
final InvocationHandler ih = (proxy, method, params) -> {
switch (method.getName()) {
@ -203,21 +199,21 @@ public class DefaultMethods {
Object proxy = Proxy.newProxyInstance(loader, intfs, ih);
if (proxyInterface == I1.class) {
I1 i1 = (I1) proxy;
assertEquals(i1.m(), expected);
assertEquals(expected, i1.m());
} else if (proxyInterface == I2.class) {
I2 i2 = (I2) proxy;
assertEquals(i2.m(), expected);
assertEquals(expected, i2.m());
} else if (proxyInterface == I3.class) {
I3 i3 = (I3) proxy;
assertEquals(i3.m(), expected);
assertEquals(expected, i3.m());
} else if (proxyInterface == I4.class) {
I4 i4 = (I4) proxy;
assertEquals(i4.m(), expected);
assertEquals(expected, i4.m());
} else {
throw new UnsupportedOperationException(proxyInterface.toString());
}
// invoke via InvocationHandler.invokeDefaultMethod directly
assertEquals(InvocationHandler.invokeDefault(proxy, proxyInterface.getMethod("m")), expected);
assertEquals(expected, InvocationHandler.invokeDefault(proxy, proxyInterface.getMethod("m")));
}
// invoke I12 default methods with parameters and var args
@ -236,12 +232,12 @@ public class DefaultMethods {
};
ClassLoader loader = DefaultMethods.class.getClassLoader();
I12 i12 = (I12) Proxy.newProxyInstance(loader, new Class<?>[] { I12.class }, ih);
assertEquals(i12.sum(1, 2), 3);
assertEquals(i12.concat(1, 2, 3, 4), new Object[]{1, 2, 3, 4});
assertEquals(3, i12.sum(1, 2));
assertArrayEquals(new Object[]{1, 2, 3, 4}, i12.concat(1, 2, 3, 4));
Method m = I12.class.getMethod("concat", Object.class, Object[].class);
assertTrue(m.isDefault());
assertEquals(InvocationHandler.invokeDefault(i12, m, 100, new Object[] {"foo", true, "bar"}),
new Object[] {100, "foo", true, "bar"});
assertArrayEquals(new Object[] {100, "foo", true, "bar"}, (Object[])
InvocationHandler.invokeDefault(i12, m, 100, new Object[] {"foo", true, "bar"}));
}
// test a no-arg default method with and without arguments passed in the invocation
@ -250,13 +246,13 @@ public class DefaultMethods {
ClassLoader loader = DefaultMethods.class.getClassLoader();
Object proxy = Proxy.newProxyInstance(loader, new Class<?>[]{I4.class}, HANDLER);
Method m1 = I4.class.getMethod("m");
assertTrue(m1.getDeclaringClass() == I4.class);
assertSame(I4.class, m1.getDeclaringClass());
assertTrue(m1.isDefault());
InvocationHandler.invokeDefault(proxy, m1);
InvocationHandler.invokeDefault(proxy, m1, new Object[0]);
Method m2 = I4.class.getMethod("mix", int.class, String.class);
assertTrue(m1.getDeclaringClass() == I4.class);
assertSame(I4.class, m1.getDeclaringClass());
assertTrue(m1.isDefault());
InvocationHandler.invokeDefault(proxy, m2, Integer.valueOf(100), "foo");
}
@ -267,38 +263,37 @@ public class DefaultMethods {
I3 proxy = (I3)Proxy.newProxyInstance(loader, new Class<?>[]{I3.class}, HANDLER);
Method m = I3.class.getMethod("m3", String[].class);
assertTrue(m.isVarArgs() && m.isDefault());
assertEquals(proxy.m3("a", "b", "cde"), 5);
assertEquals(InvocationHandler.invokeDefault(proxy, m, (Object)new String[] { "a", "bc" }), 3);
assertEquals(5, proxy.m3("a", "b", "cde"));
assertEquals(3, InvocationHandler.invokeDefault(proxy, m, (Object)new String[] { "a", "bc" }));
}
/*
* Invoke I12::m which is an abstract method
*/
@Test(expectedExceptions = {IllegalArgumentException.class})
@Test
public void invokeAbstractMethod() throws Exception {
ClassLoader loader = DefaultMethods.class.getClassLoader();
I12 proxy = (I12) Proxy.newProxyInstance(loader, new Class<?>[]{I12.class}, HANDLER);
Method method = I12.class.getMethod("m");
assertTrue(method.getDeclaringClass() == I12.class);
assertSame(I12.class, method.getDeclaringClass());
assertFalse(method.isDefault());
proxy.m();
assertThrows(IllegalArgumentException.class, () -> proxy.m());
}
/*
* Invoke a non proxy (default) method with parameters
*/
@Test(expectedExceptions = {IllegalArgumentException.class})
@Test
public void invokeNonProxyMethod() throws Throwable {
ClassLoader loader = DefaultMethods.class.getClassLoader();
I3 proxy = (I3) Proxy.newProxyInstance(loader, new Class<?>[]{I3.class}, HANDLER);
Method m = I4.class.getMethod("mix", int.class, String.class);
assertTrue(m.isDefault());
InvocationHandler.invokeDefault(proxy, m);
assertThrows(IllegalArgumentException.class, () -> InvocationHandler.invokeDefault(proxy, m));
}
// negative cases
@DataProvider(name = "negativeCases")
private Object[][] negativeCases() {
private static Object[][] negativeCases() {
return new Object[][]{
// I4::m overrides I1::m and I2::m
new Object[] { new Class<?>[]{I4.class}, I1.class, "m" },
@ -315,25 +310,20 @@ public class DefaultMethods {
};
}
@Test(dataProvider = "negativeCases", expectedExceptions = {IllegalArgumentException.class})
@ParameterizedTest
@MethodSource("negativeCases")
public void testNegativeCase(Class<?>[] interfaces, Class<?> defc, String name)
throws Throwable {
ClassLoader loader = DefaultMethods.class.getClassLoader();
Object proxy = Proxy.newProxyInstance(loader, interfaces, HANDLER);
try {
Method method = defc.getDeclaredMethod(name);
InvocationHandler.invokeDefault(proxy, method);
} catch (Throwable e) {
System.out.format("%s method %s::%s exception thrown: %s%n",
Arrays.toString(interfaces), defc.getName(), name, e.getMessage());
throw e;
}
assertThrows(IllegalArgumentException.class, () ->
InvocationHandler.invokeDefault(proxy, method));
}
@DataProvider(name = "illegalArguments")
private Object[][] illegalArguments() {
return new Object[][] {
new Object[] { new Object[0]},
private static Object[] illegalArguments() {
return new Object[] {
new Object[] { null },
new Object[] { new Object[] { 100 }},
new Object[] { new Object[] { 100, "foo", 100 }},
new Object[] { new Object[] { 100L, "foo" }},
@ -342,21 +332,18 @@ public class DefaultMethods {
};
}
@Test(dataProvider = "illegalArguments", expectedExceptions = {IllegalArgumentException.class})
@ParameterizedTest
@MethodSource("illegalArguments")
public void testIllegalArgument(Object[] args) throws Throwable {
ClassLoader loader = DefaultMethods.class.getClassLoader();
I4 proxy = (I4)Proxy.newProxyInstance(loader, new Class<?>[]{I4.class}, HANDLER);
Method m = I4.class.getMethod("mix", int.class, String.class);
assertTrue(m.isDefault());
if (args.length == 0) {
// substitute empty args with null since @DataProvider doesn't allow null array
args = null;
}
InvocationHandler.invokeDefault(proxy, m, args);
assertThrows(IllegalArgumentException.class, () ->
InvocationHandler.invokeDefault(proxy, m, args));
}
@DataProvider(name = "throwables")
private Object[][] throwables() {
private static Object[][] throwables() {
return new Object[][] {
new Object[] { new IOException() },
new Object[] { new IllegalArgumentException() },
@ -367,16 +354,14 @@ public class DefaultMethods {
};
}
@Test(dataProvider = "throwables")
@ParameterizedTest
@MethodSource("throwables")
public void testInvocationException(Throwable exception) throws Throwable {
ClassLoader loader = DefaultMethods.class.getClassLoader();
IX proxy = (IX)Proxy.newProxyInstance(loader, new Class<?>[]{IX.class}, HANDLER);
Method m = IX.class.getMethod("doThrow", Throwable.class);
try {
InvocationHandler.invokeDefault(proxy, m, exception);
} catch (Throwable e) {
assertEquals(e, exception);
}
assertSame(exception, assertThrows(Throwable.class, () ->
InvocationHandler.invokeDefault(proxy, m, exception)));
}
private static final InvocationHandler HANDLER = (proxy, method, params) -> {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 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
@ -24,7 +24,7 @@
/*
* @test
* @bug 8250219
* @run testng HiddenProxyInterface
* @run junit HiddenProxyInterface
*/
import java.lang.invoke.MethodHandles;
@ -35,8 +35,8 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
public class HiddenProxyInterface {
private static final Path CLASSES_DIR = Paths.get(System.getProperty("test.classes"));
@ -45,18 +45,19 @@ public class HiddenProxyInterface {
void m();
}
@Test(expectedExceptions = { IllegalArgumentException.class })
@Test
public void testHiddenInterface() throws Exception {
Path classFile = CLASSES_DIR.resolve("HiddenProxyInterface$Intf.class");
byte[] bytes = Files.readAllBytes(classFile);
Class<?> hiddenIntf = MethodHandles.lookup().defineHiddenClass(bytes, false).lookupClass();
Proxy.newProxyInstance(HiddenProxyInterface.class.getClassLoader(),
assertThrows(IllegalArgumentException.class, () -> Proxy.newProxyInstance(
HiddenProxyInterface.class.getClassLoader(),
new Class<?>[]{ hiddenIntf },
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
});
}));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 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
@ -23,14 +23,15 @@
import java.lang.reflect.Proxy;
import org.testng.Assert;
import org.testng.annotations.Test;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
/*
* @test
* @bug 8285401
* @summary Avoid initialization of parameter types in proxy construction
* @run testng LazyInitializationTest
* @run junit LazyInitializationTest
*/
public final class LazyInitializationTest {
private static volatile boolean initialized = false;
@ -50,9 +51,9 @@ public final class LazyInitializationTest {
Intf value = (Intf) Proxy.newProxyInstance(LazyInitializationTest.class.getClassLoader(),
new Class<?>[]{ Intf.class },
(proxy, method, args) -> null);
Assert.assertFalse(initialized, "parameter type initialized unnecessarily");
assertFalse(initialized, "parameter type initialized unnecessarily");
value.m(new Parameter());
Assert.assertTrue(initialized, "parameter type initialized after instantiation");
assertTrue(initialized, "parameter type initialized after instantiation");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 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
@ -32,17 +32,17 @@ import java.util.List;
import jdk.test.lib.compiler.CompilerUtils;
import static jdk.test.lib.process.ProcessTools.executeTestJava;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
/**
/*
* @test
* @library /test/lib
* @modules jdk.compiler
* @build ProxyClassAccessTest q.NP
* jdk.test.lib.compiler.CompilerUtils
* @run testng ProxyClassAccessTest
* @run junit ProxyClassAccessTest
* @summary Driver for testing proxy class doesn't have access to
* types referenced by proxy interfaces
*/
@ -61,8 +61,8 @@ public class ProxyClassAccessTest {
/**
* Compiles all modules used by the test
*/
@BeforeTest
public void compileAll() throws Exception {
@BeforeAll
public static void compileAll() throws Exception {
for (String mn : modules) {
Path msrc = SRC_DIR.resolve(mn);
assertTrue(CompilerUtils.compile(msrc, MODS_DIR, "--module-source-path", SRC_DIR.toString()));
@ -80,7 +80,7 @@ public class ProxyClassAccessTest {
.errorTo(System.out)
.getExitValue();
assertTrue(exitValue == 0);
assertEquals(0, exitValue);
}
/**
@ -105,16 +105,10 @@ public class ProxyClassAccessTest {
}
private void checkIAE(ClassLoader loader, Class<?>[] interfaces) throws Throwable {
try {
Proxy.getProxyClass(loader, interfaces);
throw new RuntimeException("Expected IllegalArgumentException thrown");
} catch (IllegalArgumentException e) {}
assertThrows(IllegalArgumentException.class, () -> Proxy.getProxyClass(loader, interfaces));
try {
Proxy.newProxyInstance(loader, interfaces,
(proxy, m, params) -> { throw new RuntimeException(m.toString()); });
throw new RuntimeException("Expected IllegalArgumentException thrown");
} catch (IllegalArgumentException e) {}
assertThrows(IllegalArgumentException.class, () -> Proxy.newProxyInstance(loader, interfaces,
(proxy, m, params) -> { throw new RuntimeException(m.toString()); }));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 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
@ -32,17 +32,18 @@ import java.util.Arrays;
import jdk.test.lib.compiler.CompilerUtils;
import static jdk.test.lib.process.ProcessTools.executeTestJava;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
/**
/*
* @test
* @library /test/lib
* @modules jdk.compiler
* @build ProxyTest jdk.test.lib.process.ProcessTools
* jdk.test.lib.compiler.CompilerUtils
* @run testng ProxyLayerTest
* @run junit ProxyLayerTest
* @summary Test proxies to implement interfaces in a layer
*/
@ -62,8 +63,8 @@ public class ProxyLayerTest {
/**
* Compiles all modules used by the test
*/
@BeforeTest
public void compileAll() throws Exception {
@BeforeAll
public static void compileAll() throws Exception {
for (String mn : modules) {
Path msrc = SRC_DIR.resolve(mn);
assertTrue(CompilerUtils.compile(msrc, MODS_DIR, "--module-source-path", SRC_DIR.toString()));
@ -102,7 +103,7 @@ public class ProxyLayerTest {
assertTrue(proxyClass.getModule().isNamed());
assertTrue(pkg.isSealed());
assertTrue(proxyClass.getModule().isExported(pkg.getName()));
assertEquals(proxyClass.getModule().getLayer(), null);
assertNull(proxyClass.getModule().getLayer());
}
/**
@ -134,7 +135,7 @@ public class ProxyLayerTest {
assertTrue(proxyClass.getModule().isNamed());
assertTrue(pkg.isSealed());
assertFalse(proxyClass.getModule().isExported(pkg.getName()));
assertEquals(proxyClass.getModule().getLayer(), null);
assertNull(proxyClass.getModule().getLayer());
}
/**
@ -164,15 +165,8 @@ public class ProxyLayerTest {
}
private void checkIAE(ClassLoader loader, Class<?>[] interfaces) {
try {
Proxy.getProxyClass(loader, interfaces);
throw new RuntimeException("Expected IllegalArgumentException thrown");
} catch (IllegalArgumentException e) {}
try {
Proxy.newProxyInstance(loader, interfaces, handler);
throw new RuntimeException("Expected IllegalArgumentException thrown");
} catch (IllegalArgumentException e) {}
assertThrows(IllegalArgumentException.class, () -> Proxy.getProxyClass(loader, interfaces));
assertThrows(IllegalArgumentException.class, () -> Proxy.newProxyInstance(loader, interfaces, handler));
}
private final static InvocationHandler handler =

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 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
@ -29,17 +29,17 @@ import java.util.List;
import jdk.test.lib.compiler.CompilerUtils;
import static jdk.test.lib.process.ProcessTools.executeTestJava;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
/**
/*
* @test
* @library /test/lib
* @modules jdk.compiler
* @build ProxyTest q.U
* jdk.test.lib.compiler.CompilerUtils
* @run testng ProxyTest
* @run junit ProxyTest
* @summary Driver for testing proxies accessing interfaces in named modules
*/
@ -59,8 +59,8 @@ public class ProxyTest {
/**
* Compiles all modules used by the test
*/
@BeforeTest
public void compileAll() throws Exception {
@BeforeAll
public static void compileAll() throws Exception {
for (String mn : modules) {
Path msrc = SRC_DIR.resolve(mn);
assertTrue(CompilerUtils.compile(msrc, MODS_DIR, "--module-source-path", SRC_DIR.toString()));
@ -79,7 +79,7 @@ public class ProxyTest {
.errorTo(System.out)
.getExitValue();
assertTrue(exitValue == 0);
assertEquals(0, exitValue);
}
/**
@ -95,6 +95,6 @@ public class ProxyTest {
.errorTo(System.out)
.getExitValue();
assertTrue(exitValue == 0);
assertEquals(0, exitValue);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* 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
@ -24,15 +24,15 @@
/*
* @test
* @bug 8269351
* @run testng SealedInterfaceTest
* @run junit SealedInterfaceTest
*/
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
public class SealedInterfaceTest {
sealed interface Intf permits NonSealedInterface {
@ -43,16 +43,17 @@ public class SealedInterfaceTest {
void m2();
}
@Test(expectedExceptions = { IllegalArgumentException.class })
@Test
public void testSealedInterface() {
Proxy.newProxyInstance(SealedInterfaceTest.class.getClassLoader(),
assertThrows(IllegalArgumentException.class, () -> Proxy.newProxyInstance(
SealedInterfaceTest.class.getClassLoader(),
new Class<?>[]{ Intf.class },
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
});
}));
}
@Test

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 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
@ -21,10 +21,10 @@
* questions.
*/
/**
/*
* @test
* @bug 8022795
* @run testng TestVarArgs
* @run junit TestVarArgs
* @summary Verify if a method defined in a proxy interface has ACC_VARARGS set
*/
@ -34,11 +34,10 @@ import java.lang.invoke.MethodType;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class TestVarArgs {
interface I {
@ -48,8 +47,7 @@ public class TestVarArgs {
Object call(Object[] values);
}
@DataProvider(name = "proxyInterfaces")
public Object[][] proxyInterfaces() {
public static Object[][] proxyInterfaces() {
return new Object[][] {
{ new Class<?>[] { I.class }, true},
{ new Class<?>[] { J.class }, false},
@ -58,11 +56,12 @@ public class TestVarArgs {
};
}
@Test(dataProvider = "proxyInterfaces")
@ParameterizedTest
@MethodSource("proxyInterfaces")
public void testMethod(Class<?>[] proxyInterfaces, boolean isVarArgs) throws Throwable {
// check if the first proxy interface with the method named "call" declares var result
Method m = proxyInterfaces[0].getMethod("call", Object[].class);
assertTrue(m.isVarArgs() == isVarArgs);
assertEquals(isVarArgs, m.isVarArgs());
// the method in the generated proxy class should match the method
// declared in the proxy interface
@ -71,19 +70,19 @@ public class TestVarArgs {
Class<?> proxyClass = proxy.getClass();
assertTrue(Proxy.isProxyClass(proxyClass));
Method method = proxyClass.getMethod("call", Object[].class);
assertTrue(method.isVarArgs() == isVarArgs);
assertEquals(isVarArgs, method.isVarArgs());
Object params = new Object[] { "foo", "bar", "goo" };
Object result;
Object[] params = new Object[] { "foo", "bar", "goo" };
Object[] result;
// test reflection
result = method.invoke(proxy, params);
assertEquals(result, params);
result = (Object[]) method.invoke(proxy, new Object[] {params});
assertEquals(params, result);
// test method handle
MethodHandle mh = MethodHandles.lookup().findVirtual(proxyClass, "call",
MethodType.methodType(Object.class, Object[].class));
assertTrue(mh.isVarargsCollector() == isVarArgs);
assertEquals(isVarArgs, mh.isVarargsCollector());
MethodHandle mhVarArity = mh;
MethodHandle mhFixedArity = mh;
if (isVarArgs) {
@ -91,18 +90,18 @@ public class TestVarArgs {
} else {
mhVarArity = mh.asVarargsCollector(Object[].class);
}
result = mhVarArity.invoke(proxy, "foo", "bar", "goo");
assertEquals(result, params);
result = (Object[]) mhVarArity.invoke(proxy, "foo", "bar", "goo");
assertArrayEquals(params, result);
result = mhFixedArity.invoke(proxy, params);
assertEquals(result, params);
result = (Object[]) mhFixedArity.invoke(proxy, params);
assertArrayEquals(params, result);
if (!isVarArgs) {
MethodType mt = MethodType.methodType(Object.class, Object.class, String.class, String.class, String.class);
mh = mh.asVarargsCollector(Object[].class).asType(mt);
}
result = mh.invoke(proxy, "foo", "bar", "goo");
assertEquals(result, params);
result = (Object[]) mh.invoke(proxy, "foo", "bar", "goo");
assertArrayEquals(params, result);
}
private static final InvocationHandler IH = new InvocationHandler() {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 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
@ -25,16 +25,17 @@ import java.lang.reflect.*;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
/*
* @test
* @bug 8159746
* @summary Test invoking a default method in a non-public proxy interface
* @build p.Foo p.Bar p.ProxyMaker
* @run testng DefaultMethodProxy
* @run junit DefaultMethodProxy
*/
public class DefaultMethodProxy {
public interface I {
@ -42,7 +43,7 @@ public class DefaultMethodProxy {
}
@Test
public static void publicInterface() throws ReflectiveOperationException {
public void publicInterface() throws ReflectiveOperationException {
// create a proxy instance of a public proxy interface should succeed
Proxy proxy = (Proxy)Proxy.newProxyInstance(DefaultMethodProxy.class.getClassLoader(),
new Class<?>[] { I.class }, IH);
@ -50,11 +51,9 @@ public class DefaultMethodProxy {
testDefaultMethod(proxy, "I");
// can get the invocation handler
assertTrue(Proxy.getInvocationHandler(proxy) == IH);
assertSame(IH, Proxy.getInvocationHandler(proxy));
}
@DataProvider(name = "nonPublicIntfs")
private static Object[][] nonPublicIntfs() throws ClassNotFoundException {
Class<?> fooClass = Class.forName("p.Foo");
Class<?> barClass = Class.forName("p.Bar");
@ -65,8 +64,9 @@ public class DefaultMethodProxy {
};
}
@Test(dataProvider = "nonPublicIntfs")
public static void hasPackageAccess(Class<?>[] intfs, String expected) throws ReflectiveOperationException {
@ParameterizedTest
@MethodSource("nonPublicIntfs")
public void hasPackageAccess(Class<?>[] intfs, String expected) throws ReflectiveOperationException {
Proxy proxy = (Proxy)Proxy.newProxyInstance(DefaultMethodProxy.class.getClassLoader(), intfs, IH);
testDefaultMethod(proxy, expected);
@ -75,19 +75,13 @@ public class DefaultMethodProxy {
}
// IAE thrown at invocation time
@Test(dataProvider = "nonPublicIntfs", expectedExceptions = {IllegalAccessException.class})
public static void noPackageAccess(Class<?>[] intfs, String ignored) throws Throwable {
@ParameterizedTest
@MethodSource("nonPublicIntfs")
public void noPackageAccess(Class<?>[] intfs, String ignored) throws Throwable {
Proxy proxy = (Proxy)Proxy.newProxyInstance(DefaultMethodProxy.class.getClassLoader(), intfs, IH_NO_ACCESS);
try {
testDefaultMethod(proxy, "dummy");
} catch (InvocationTargetException e) {
// unwrap the exception
if (e.getCause() instanceof UndeclaredThrowableException) {
Throwable cause = e.getCause();
throw cause.getCause();
}
throw e;
}
InvocationTargetException ite = assertThrows(InvocationTargetException.class, () -> testDefaultMethod(proxy, "dummy"));
var ute = assertInstanceOf(UndeclaredThrowableException.class, ite.getCause(), "unwrap the InvocationTargetException");
assertInstanceOf(IllegalAccessException.class, ute.getCause(), "unwrap the UndeclaredThrowableException");
}
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 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
@ -27,13 +27,13 @@
* @summary Test sharing of annotations between Executable/Field instances.
* Sharing should not be noticeable when performing mutating
* operations.
* @run testng AnnotationSharing
* @run junit AnnotationSharing
*/
import java.lang.annotation.*;
import java.lang.reflect.*;
import org.testng.annotations.Test;
import org.junit.jupiter.api.Test;
public class AnnotationSharing {
@Test

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* 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
@ -27,7 +27,7 @@
* @library /test/lib/
* @modules jdk.compiler
* @build CustomLoaderTest jdk.test.lib.compiler.CompilerUtils
* @run testng/othervm CustomLoaderTest
* @run junit/othervm CustomLoaderTest
*
* @summary Test method whose parameter types and return type are not visible to the caller.
*/
@ -42,27 +42,23 @@ import java.nio.file.Paths;
import java.util.concurrent.atomic.AtomicInteger;
import jdk.test.lib.compiler.CompilerUtils;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class CustomLoaderTest {
private static final Path CLASSES = Paths.get("classes");
@BeforeTest
public void setup() throws IOException {
@BeforeAll
public static void setup() throws IOException {
String src = System.getProperty("test.src", ".");
String classpath = System.getProperty("test.classes", ".");
boolean rc = CompilerUtils.compile(Paths.get(src, "ReflectTest.java"), CLASSES, "-cp", classpath);
if (!rc) {
throw new RuntimeException("fail compilation");
}
try {
Class<?> p = Class.forName("ReflectTest$P");
fail("should not be visible to this loader");
} catch (ClassNotFoundException e) {
e.printStackTrace();
fail("fail compilation");
}
assertThrows(ClassNotFoundException.class, () -> Class.forName("ReflectTest$P"),
"should not be visible to this loader");
}
@Test
@ -72,17 +68,17 @@ public class CustomLoaderTest {
Method m1 = loader1.findMethod();
Method m2 = loader2.findMethod();
assertTrue(m1.getDeclaringClass() != m2.getDeclaringClass());
assertNotSame(m1.getDeclaringClass(), m2.getDeclaringClass());
assertTrue(m1.getDeclaringClass() == loader1.c);
assertTrue(m2.getDeclaringClass() == loader2.c);
assertSame(loader1.c, m1.getDeclaringClass());
assertSame(loader2.c, m2.getDeclaringClass());
Object o1 = m1.invoke(loader1.c.newInstance(), loader1.p.newInstance(), loader1.q.newInstance());
Object o2 = m2.invoke(loader2.c.newInstance(), loader2.p.newInstance(), loader2.q.newInstance());
assertTrue(o1.getClass() != o2.getClass());
assertTrue(o1.getClass() == loader1.r);
assertTrue(o2.getClass() == loader2.r);
assertNotSame(o1.getClass(), o2.getClass());
assertSame(loader1.r, o1.getClass());
assertSame(loader2.r, o2.getClass());
}
static class TestLoader extends URLClassLoader {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 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
@ -29,7 +29,7 @@
* @library /test/lib/
* @modules jdk.compiler
* @build ReflectionCallerCacheTest Members jdk.test.lib.compiler.CompilerUtils
* @run testng/othervm ReflectionCallerCacheTest
* @run junit/othervm ReflectionCallerCacheTest
*/
import java.io.IOException;
@ -44,16 +44,16 @@ import java.util.concurrent.Callable;
import jdk.test.lib.compiler.CompilerUtils;
import jdk.test.lib.util.ForceGC;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class ReflectionCallerCacheTest {
private static final Path CLASSES = Paths.get("classes");
private static final ReflectionCallerCacheTest TEST = new ReflectionCallerCacheTest();
@BeforeTest
public void setup() throws IOException {
@BeforeAll
public static void setup() throws IOException {
String src = System.getProperty("test.src", ".");
String classpath = System.getProperty("test.classes", ".");
boolean rc = CompilerUtils.compile(Paths.get(src, "AccessTest.java"), CLASSES, "-cp", classpath);
@ -61,8 +61,8 @@ public class ReflectionCallerCacheTest {
throw new RuntimeException("fail compilation");
}
}
@DataProvider(name = "memberAccess")
public Object[][] memberAccess() {
public static Object[][] memberAccess() {
return new Object[][] {
{ "AccessTest$PublicConstructor" },
{ "AccessTest$PublicMethod" },
@ -102,8 +102,9 @@ public class ReflectionCallerCacheTest {
}
}
@Test(dataProvider = "memberAccess")
private void load(String classname) throws Exception {
@ParameterizedTest
@MethodSource("memberAccess")
void load(String classname) throws Exception {
WeakReference<?> weakLoader = loadAndRunClass(classname);
// Force garbage collection to trigger unloading of class loader

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 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
@ -25,17 +25,15 @@
* @test
* @bug 8257598
* @summary check that Record::equals uses the fields and not the accessors for the comparison
* @run testng CheckEqualityIsBasedOnFields
* @run junit CheckEqualityIsBasedOnFields
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class CheckEqualityIsBasedOnFields {
public record R01(boolean x) {
@ -91,8 +89,7 @@ public class CheckEqualityIsBasedOnFields {
}
}
@DataProvider(name = "recordData")
public Object[][] recordTypeAndExpectedValue() {
public static Object[][] recordTypeAndExpectedValue() {
return new Object[][] {
new Object[] { R01.class, boolean.class, new Object[]{true, false} },
new Object[] { R02.class, byte.class, new Object[]{(byte)0, (byte)1, (byte)2, (byte)3, (byte)4, (byte)5,
@ -112,7 +109,8 @@ public class CheckEqualityIsBasedOnFields {
};
}
@Test(dataProvider = "recordData")
@ParameterizedTest
@MethodSource("recordTypeAndExpectedValue")
public void testEqualsDoesntUseAccessors(Class<?> clazz, Class<?> componentClass, Object[] expectedXValues) throws Exception {
Constructor<?> ctor;
Method getter, equalsMethod;
@ -125,8 +123,8 @@ public class CheckEqualityIsBasedOnFields {
System.out.println(rec1.toString());
System.out.println(rec2.toString());
assertFalse((boolean) equalsMethod.invoke(rec1, rec2));
assertNotEquals(expectedXValues[i], expectedXValues[i + expectedXValues.length / 2]);
assertEquals(getter.invoke(rec1), getter.invoke(rec2));
assertNotEquals(expectedXValues[i + expectedXValues.length / 2], expectedXValues[i]);
assertEquals(getter.invoke(rec2), getter.invoke(rec1));
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 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
@ -26,32 +26,31 @@
* @bug 8255560
* @summary Class::isRecord should check that the current class is final and not abstract
* @library /test/lib
* @run testng/othervm IsRecordTest
* @run junit/othervm IsRecordTest
*/
import java.lang.classfile.ClassFile;
import java.lang.constant.ClassDesc;
import java.lang.reflect.AccessFlag;
import java.util.List;
import java.util.Map;
import java.lang.classfile.attribute.RecordAttribute;
import java.lang.classfile.attribute.RecordComponentInfo;
import jdk.test.lib.ByteCodeLoader;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static java.lang.System.out;
import static java.lang.classfile.ClassFile.ACC_ABSTRACT;
import static java.lang.classfile.ClassFile.ACC_FINAL;
import static java.lang.constant.ConstantDescs.CD_int;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.*;
public class IsRecordTest {
@DataProvider(name = "scenarios")
public Object[][] scenarios() {
public static Object[][] scenarios() {
return new Object[][] {
// isFinal, isAbstract, extendJLR, withRecAttr, expectIsRecord
{ false, false, false, true, false },
@ -75,7 +74,8 @@ public class IsRecordTest {
* iii) direct subclass of j.l.Record (or not), along with the presence or
* absence of a record attribute.
*/
@Test(dataProvider = "scenarios")
@ParameterizedTest
@MethodSource("scenarios")
public void testDirectSubClass(boolean isFinal,
boolean isAbstract,
boolean extendsJLR,
@ -92,9 +92,8 @@ public class IsRecordTest {
Class<?> cls = ByteCodeLoader.load("C", classBytes);
out.println("cls=%s, Record::isAssignable=%s, isRecord=%s"
.formatted(cls, Record.class.isAssignableFrom(cls), cls.isRecord()));
assertEquals(cls.isRecord(), expectIsRecord);
var getRecordComponents = cls.getRecordComponents();
assertTrue(expectIsRecord ? getRecordComponents != null : getRecordComponents == null);
assertEquals(expectIsRecord, cls.isRecord());
assertEquals(expectIsRecord, cls.getRecordComponents() != null);
}
/**
@ -102,7 +101,8 @@ public class IsRecordTest {
* along with the presence or absence of a record attribute, where the class has
* a superclass whose superclass is j.l.Record.
*/
@Test(dataProvider = "scenarios")
@ParameterizedTest
@MethodSource("scenarios")
public void testIndirectSubClass(boolean isFinal,
boolean isAbstract,
boolean unused1,
@ -127,8 +127,8 @@ public class IsRecordTest {
.formatted(cls, Record.class.isAssignableFrom(cls), cls.isRecord()));
assertFalse(supFooCls.isRecord());
assertFalse(subFooCls.isRecord());
assertEquals(supFooCls.getRecordComponents(), null);
assertEquals(subFooCls.getRecordComponents(), null);
assertNull(supFooCls.getRecordComponents());
assertNull(subFooCls.getRecordComponents());
}
/** Tests record-ness properties of traditionally compiled classes. */
@ -137,23 +137,23 @@ public class IsRecordTest {
out.println("\n--- testBasicRecords ---");
record EmptyRecord () { }
assertTrue(EmptyRecord.class.isRecord());
assertEquals(EmptyRecord.class.getRecordComponents().length, 0);
assertEquals(0, EmptyRecord.class.getRecordComponents().length);
record FooRecord (int x) { }
assertTrue(FooRecord.class.isRecord());
assertTrue(FooRecord.class.getRecordComponents() != null);
assertNotNull(FooRecord.class.getRecordComponents());
final record FinalFooRecord (int x) { }
assertTrue(FinalFooRecord.class.isRecord());
assertTrue(FinalFooRecord.class.getRecordComponents() != null);
assertNotNull(FinalFooRecord.class.getRecordComponents());
class A { }
assertFalse(A.class.isRecord());
assertFalse(A.class.getRecordComponents() != null);
assertNull(A.class.getRecordComponents());
final class B { }
assertFalse(B.class.isRecord());
assertFalse(B.class.getRecordComponents() != null);
assertNull(B.class.getRecordComponents());
}
// -- infra

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 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
@ -27,16 +27,17 @@
* @summary reflection test for records
* @build R10
* @compile RecordReflectionTest.java
* @run testng/othervm RecordReflectionTest
* @run junit/othervm RecordReflectionTest
*/
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.List;
import org.testng.annotations.*;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@Test
public class RecordReflectionTest {
class NoRecord {}
@ -78,8 +79,7 @@ public class RecordReflectionTest {
R13 {} // compact constructor, will contain mandated parameters
}
@DataProvider(name = "recordClasses")
public Object[][] recordClassData() {
public static Object[][] recordClassData() {
return List.of(R1.class,
R2.class,
R3.class,
@ -96,17 +96,17 @@ public class RecordReflectionTest {
).stream().map(c -> new Object[] {c}).toArray(Object[][]::new);
}
@Test(dataProvider = "recordClasses")
@ParameterizedTest
@MethodSource("recordClassData")
public void testIsRecord(Class<?> cls) {
String message = cls.toGenericString();
assertTrue(cls.isRecord());
assertTrue(cls.getSuperclass() == java.lang.Record.class);
assertTrue(cls.getRecordComponents() != null);
assertSame(Record.class, cls.getSuperclass());
assertNotNull(cls.getRecordComponents());
assertTrue(message.contains("record"), message);
}
@DataProvider(name = "notRecordClasses")
public Object[][] notRecordClasses() {
public static List<Class<?>> notRecordClasses() {
return List.of(NoRecord.class,
NoRecord[].class,
Record.class, // java.lang.Record is not itself a record class
@ -116,19 +116,18 @@ public class RecordReflectionTest {
int.class,
int[].class,
long.class,
long[].class)
.stream().map(c -> new Object[] {c}).toArray(Object[][]::new);
long[].class);
}
@Test(dataProvider = "notRecordClasses")
@ParameterizedTest
@MethodSource("notRecordClasses")
public void testNotARecordClass(Class<?> cls) {
assertFalse(cls.isRecord());
assertFalse(cls.getSuperclass() == java.lang.Record.class);
assertTrue(cls.getRecordComponents() == null);
assertNotSame(Record.class, cls.getSuperclass());
assertNull(cls.getRecordComponents());
}
@DataProvider(name = "reflectionData")
public Object[][] reflectionData() {
public static Object[][] reflectionData() {
return new Object[][] {
new Object[] { new R1(),
0,
@ -181,7 +180,8 @@ public class RecordReflectionTest {
};
}
@Test(dataProvider = "reflectionData")
@ParameterizedTest
@MethodSource("reflectionData")
public void testRecordReflection(Object recordOb,
int numberOfComponents,
Object[] values,
@ -192,13 +192,13 @@ public class RecordReflectionTest {
Class<?> recordClass = recordOb.getClass();
assertTrue(recordClass.isRecord());
RecordComponent[] recordComponents = recordClass.getRecordComponents();
assertEquals(recordComponents.length, numberOfComponents);
assertEquals(numberOfComponents, recordComponents.length);
int i = 0;
for (RecordComponent rc : recordComponents) {
assertEquals(rc.getName(), names[i]);
assertEquals(rc.getType(), rc.getAccessor().getReturnType());
assertEquals(rc.getAccessor().invoke(recordOb), values[i]);
assertEquals(rc.getAccessor().getGenericReturnType().toString(), signatures[i],
assertEquals(names[i], rc.getName());
assertEquals(rc.getAccessor().getReturnType(), rc.getType());
assertEquals(values[i], rc.getAccessor().invoke(recordOb));
assertEquals(signatures[i], rc.getAccessor().getGenericReturnType().toString(),
String.format("signature of method \"%s\" different from expected signature \"%s\"",
rc.getAccessor().getGenericReturnType(), signatures[i]));
i++;
@ -207,7 +207,7 @@ public class RecordReflectionTest {
var constructor = recordClass.getDeclaredConstructors()[0];
i = 0;
for (var p: constructor.getParameters()) {
assertEquals(p.getParameterizedType().toString(), signatures[i],
assertEquals(signatures[i], p.getParameterizedType().toString(),
String.format("signature of method \"%s\" different from expected signature \"%s\"",
p.getType().toString(), signatures[i]));
i++;
@ -215,7 +215,7 @@ public class RecordReflectionTest {
// similar as above but testing another API
i = 0;
for (var p : constructor.getGenericParameterTypes()) {
assertEquals(p.toString(), signatures[i],
assertEquals(signatures[i], p.toString(),
String.format("signature of method \"%s\" different from expected signature \"%s\"",
p.toString(), signatures[i]));
i++;
@ -228,16 +228,17 @@ public class RecordReflectionTest {
record AnnotatedRec(@RCA int i) {}
@Test
public void testDeclAnnotationsInRecordComp() throws Throwable {
Class<?> recordClass = AnnotatedRec.class;
RecordComponent rc = recordClass.getRecordComponents()[0];
Annotation[] annos = rc.getAnnotations();
assertEquals(annos.length, 1);
assertEquals(annos[0].toString(), "@RecordReflectionTest.RCA()");
assertEquals(1, annos.length);
assertEquals("@RecordReflectionTest.RCA()", annos[0].toString());
Field f = recordClass.getDeclaredField("i");
assertEquals(f.getAnnotations().length, 1);
assertEquals(f.getAnnotations()[0].toString(), annos[0].toString());
assertEquals(1, f.getAnnotations().length);
assertEquals(annos[0].toString(), f.getAnnotations()[0].toString());
}
@Retention(RetentionPolicy.RUNTIME)
@ -246,30 +247,28 @@ public class RecordReflectionTest {
record TypeAnnotatedRec(@TYPE_USE int i) {}
@Test
public void testTypeAnnotationsInRecordComp() throws Throwable {
Class<?> recordClass = TypeAnnotatedRec.class;
RecordComponent rc = recordClass.getRecordComponents()[0];
AnnotatedType at = rc.getAnnotatedType();
Annotation[] annos = at.getAnnotations();
assertEquals(annos.length, 1);
assertEquals(annos[0].toString(), "@RecordReflectionTest.TYPE_USE()");
assertEquals(1, annos.length);
assertEquals("@RecordReflectionTest.TYPE_USE()", annos[0].toString());
Field f = recordClass.getDeclaredField("i");
assertEquals(f.getAnnotatedType().getAnnotations().length, 1);
assertEquals(f.getAnnotatedType().getAnnotations()[0].toString(), annos[0].toString());
assertEquals(1, f.getAnnotatedType().getAnnotations().length);
assertEquals(annos[0].toString(), f.getAnnotatedType().getAnnotations()[0].toString());
}
@Test
public void testReadOnlyFieldInRecord() throws Throwable {
R2 o = new R2(1, 2);
Class<?> recordClass = R2.class;
String fieldName = "i";
Field f = recordClass.getDeclaredField(fieldName);
assertTrue(f.trySetAccessible());
assertTrue(f.get(o) != null);
try {
f.set(o, null);
assertTrue(false, "should fail to set " + fieldName);
} catch (IllegalAccessException e) {
}
assertNotNull(f.get(o));
assertThrows(IllegalAccessException.class, () -> f.set(o, null));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 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
@ -26,18 +26,17 @@
* @bug 8227046
* @summary reflection test for sealed classes
* @compile SealedClassesReflectionTest.java
* @run testng/othervm SealedClassesReflectionTest
* @run junit/othervm SealedClassesReflectionTest
*/
import java.lang.annotation.*;
import java.lang.constant.ClassDesc;
import java.lang.reflect.*;
import java.util.Arrays;
import java.util.List;
import org.testng.annotations.*;
import static org.testng.Assert.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@Test
public class SealedClassesReflectionTest {
sealed class SealedClass1 permits FinalSubclass1, NonSealedSubclass1 {}
@ -68,8 +67,7 @@ public class SealedClassesReflectionTest {
sealed class SealedSubclass2 implements SealedInt3 permits NonSealedSubclass2 {}
non-sealed class NonSealedSubclass2 extends SealedSubclass2 {}
@DataProvider(name = "sealedClasses")
public Object[][] sealedClassesData() {
public static List<Class<?>> sealedClassesData() {
return List.of(
SealedClass1.class,
SealedClass2.class,
@ -79,19 +77,19 @@ public class SealedClassesReflectionTest {
SealedInt2.class,
SealedInt3.class,
SealedSubInt1.class
).stream().map(c -> new Object[] {c}).toArray(Object[][]::new);
);
}
@Test(dataProvider = "sealedClasses")
@ParameterizedTest
@MethodSource("sealedClassesData")
public void testSealedClasses(Class<?> cls) {
assertTrue(cls.isSealed());
assertTrue(!Modifier.isFinal(cls.getModifiers()));
assertTrue(cls.getPermittedSubclasses() != null);
assertFalse(Modifier.isFinal(cls.getModifiers()));
assertNotNull(cls.getPermittedSubclasses());
assertTrue(cls.getPermittedSubclasses().length > 0);
}
@DataProvider(name = "notSealedClasses")
public Object[][] notSealedClassesData() {
public static List<Class<?>> notSealedClassesData() {
return List.of(
Object.class,
void.class, Void.class, Void[].class,
@ -104,34 +102,34 @@ public class SealedClassesReflectionTest {
double.class, double[].class, Double.class, Double[].class,
boolean.class, boolean[].class, Boolean.class, Boolean[].class,
String.class, String[].class
).stream().map(c -> new Object[] {c}).toArray(Object[][]::new);
);
}
@Test(dataProvider = "notSealedClasses")
@ParameterizedTest
@MethodSource("notSealedClassesData")
public void testNotSealedClasses(Class<?> cls) {
assertTrue(!cls.isSealed());
assertTrue(cls.getPermittedSubclasses() == null);
assertFalse(cls.isSealed());
assertNull(cls.getPermittedSubclasses());
}
@DataProvider(name = "non_sealedClasses")
public Object[][] non_sealedClassesData() {
public static List<Class<?>> non_sealedClassesData() {
return List.of(
NonSealedSubclass1.class,
NonSealedSubInt1.class,
NonSealedSubclass2.class
).stream().map(c -> new Object[] {c}).toArray(Object[][]::new);
);
}
@Test(dataProvider = "non_sealedClasses")
@ParameterizedTest
@MethodSource("non_sealedClassesData")
public void testnon_sealedClasses(Class<?> cls) {
assertTrue(!cls.isSealed());
assertTrue(!Modifier.isFinal(cls.getModifiers()));
assertFalse(cls.isSealed());
assertFalse(Modifier.isFinal(cls.getModifiers()));
assertTrue((cls.getSuperclass() != null && cls.getSuperclass().isSealed()) || Arrays.stream(cls.getInterfaces()).anyMatch(Class::isSealed));
assertTrue(cls.getPermittedSubclasses() == null);
assertNull(cls.getPermittedSubclasses());
}
@DataProvider(name = "reflectionData")
public Object[][] reflectionData() {
public static Object[][] reflectionData() {
return new Object[][] {
new Object[] {
SealedClass1.class,
@ -204,7 +202,8 @@ public class SealedClassesReflectionTest {
SEALED, NON_SEALED, FINAL
}
@Test(dataProvider = "reflectionData")
@ParameterizedTest
@MethodSource("reflectionData")
public void testSealedReflection(Class<?> sealedClass,
int numberOfSubclasses,
String[] subclassDescriptors,
@ -213,10 +212,10 @@ public class SealedClassesReflectionTest {
throws ReflectiveOperationException
{
assertTrue(sealedClass.isSealed());
assertTrue(sealedClass.getPermittedSubclasses().length == numberOfSubclasses);
assertEquals(numberOfSubclasses, sealedClass.getPermittedSubclasses().length);
int i = 0;
for (Class<?> cd : sealedClass.getPermittedSubclasses()) {
assertTrue(cd.getName().equals(subclassDescriptors[i]), "expected: " + subclassDescriptors[i] + " found: " + cd.getName());
assertEquals(subclassDescriptors[i], cd.getName());
i++;
}
i = 0;