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

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

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

View file

@ -0,0 +1,108 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 4987375
* @summary make sure clone() isn't reflected and that Cloneable and
* Serializable are found
*/
import java.lang.reflect.*;
import java.util.Arrays;
public class ArrayMethods {
public int failed = 0;
public static void main(String[] args) throws Exception {
ArrayMethods m = new ArrayMethods();
m.testGetMethod();
m.testGetMethods();
m.testGetDeclaredMethod();
m.testGetDeclaredMethods();
m.testGetInterfaces();
if (m.failed != 0)
throw new RuntimeException("Test failed, check log for details");
}
public void testGetMethod() {
try {
Method m = new String[0].getClass().getMethod("clone", (Class<?>[])null);
failed++;
System.out.println("getMethod(\"clone\", null) Should not find clone()");
} catch (NoSuchMethodException e) {
; //all good
}
}
public void testGetMethods() {
Method[] m = new Integer[0][0][0].getClass().getMethods();
for (Method mm : m)
if(mm.getName().contentEquals("clone")) {
failed++;
System.out.println("getMethods() Should not find clone()");
}
}
public void testGetDeclaredMethod() {
try {
Method m = new Object[0][0].getClass().getDeclaredMethod("clone", (Class<?>[])null);
failed++;
System.out.println("getDeclaredMethod(\"clone\", null) Should not find clone()");
} catch (NoSuchMethodException e) {
; //all good
}
}
public void testGetDeclaredMethods() {
Method[] m = new Throwable[0][0][0][0].getClass().getDeclaredMethods();
if (m.length != 0) {
failed++;
System.out.println("getDeclaredMethods().length should be 0");
}
}
public void testGetInterfaces() {
Class<?>[] is = new Integer[0].getClass().getInterfaces();
boolean thisFailed = false;
if (is.length != 2)
thisFailed = true;
if (!is[0].getCanonicalName().equals("java.lang.Cloneable"))
thisFailed = true;
if (!is[1].getCanonicalName().equals("java.io.Serializable"))
thisFailed = true;
if (thisFailed) {
failed++;
System.out.println(Arrays.asList(is));
System.out.println("Should contain exactly Cloneable, Serializable in that order.");
}
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8268250
* @summary Check exceptional behavior of Class.arrayType
*/
import java.lang.reflect.*;
import java.util.function.*;
public class ArrayType {
public static void main(String... args) {
expectException(() -> Void.TYPE);
expectException(() -> Array.newInstance(int.class, new int[255])
.getClass());
}
private static void expectException(Supplier<Class<?>> arrayTypeArg) {
try {
Class<?> arrayClazz = arrayTypeArg.get().arrayType();
throw new RuntimeException("Expected exception not thrown: " +
arrayClazz);
} catch (UnsupportedOperationException uoe) {
; // Expected
}
}
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4881275
* @summary (reflect) Class.cast() - typesafe cast desired
*/
public class Cast {
static class Foo {}
public static void main(String argv[]) throws Exception {
Object o = Foo.class.newInstance();
Foo f = Foo.class.cast(o);
if (f == null) throw new Error();
Foo f2 = Foo.class.cast(null);
}
}

Binary file not shown.

View file

@ -0,0 +1,11 @@
/*
*
*
* This file is used indirectly by the IsEnum.java test. The class
* file generated from this source file has class file version 48;
* i.e. it is not a version 49 class file generated by target 1.5.
*/
class EnumPoseur extends java.lang.Enum {
private EnumPoseur(){
}
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package foo;
// Loaded by a custom class loader in GetPackageTest
public class Foo {
}

View file

@ -0,0 +1,103 @@
/*
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Test Class.forPrimitiveName
* @bug 6361826
*/
import java.util.*;
public class ForPrimitiveName {
public static void main(String... args) {
positiveTests();
negativeTests();
}
private static final void positiveTests() {
/**
* immutable table mapping primitive type names to corresponding
* class objects
*/
final Map<String, Class<?>> primClasses =
Map.of("boolean", boolean.class,
"byte", byte.class,
"char", char.class,
"short", short.class,
"int", int.class,
"long", long.class,
"float", float.class,
"double", double.class,
"void", void.class);
for (var entry : primClasses.entrySet()) {
String key = entry.getKey();
Class<?> expected = entry.getValue();
Class<?> result = Class.forPrimitiveName(key);
// For java.lang.Class, equality is identity.
if (result != expected) {
throw new RuntimeException("Unexpected mapping for " + key);
}
}
}
private static final void negativeTests() {
final List<String> expectedNull =
List.of("java.lang.Object",
"java.lang.String",
// descriptor string names for primitive types
"Z", // boolean
"B", // byte
"C", // char
"D", // double
"F", // float
"I", // int
"L", // long
"S", // short
"V", // void
// Wrapper classes
"java.lang.Byte",
"java.lang.Boolean",
"java.lang.Character",
"java.lang.Short",
"java.lang.Integer",
"java.lang.Long",
"java.lang.Float",
"java.lang.Double",
"java.lang.Void");
for (var entry : expectedNull) {
Class<?> result = Class.forPrimitiveName(entry);
if (result != null ) {
throw new RuntimeException("Unexpected nonnull result for " +
entry);
}
}
}
}

View file

@ -0,0 +1,249 @@
/*
* Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6298888 6992705 8161500 6304578 8322878
* @summary Check Class.toGenericString()
*/
import java.lang.reflect.*;
import java.lang.annotation.*;
import java.util.*;
@ExpectedGenericString("public class GenericStringTest")
public class GenericStringTest {
public Map<String, Integer>[] mixed = null;
public Map<String, Integer>[][] mixed2 = null;
private static record PlatformTestCase(Class<?> clazz, String expected) {}
public static void main(String... args) throws ReflectiveOperationException {
int failures = 0;
String[][] nested = {{""}};
int[][] intArray = {{1}};
List<PlatformTestCase> platformTestCases =
List.of(new PlatformTestCase(int.class, "int"),
new PlatformTestCase(void.class, "void"),
new PlatformTestCase(args.getClass(), "java.lang.String[]"),
new PlatformTestCase(nested.getClass(), "java.lang.String[][]"),
new PlatformTestCase(intArray.getClass(), "int[][]"),
new PlatformTestCase(java.lang.Enum.class,
"public abstract class java.lang.Enum<E extends java.lang.Enum<E>>"),
new PlatformTestCase(java.util.Map.class,
"public abstract interface java.util.Map<K,V>"),
new PlatformTestCase(java.util.EnumMap.class,
"public class java.util.EnumMap<K extends java.lang.Enum<K>,V>"),
new PlatformTestCase(java.util.EventListenerProxy.class,
"public abstract class java.util.EventListenerProxy<T extends java.util.EventListener>"),
// Sealed class
new PlatformTestCase(java.lang.ref.Reference.class,
"public abstract sealed class java.lang.ref.Reference<T>"),
// non-sealed class
new PlatformTestCase(java.lang.ref.WeakReference.class,
"public non-sealed class java.lang.ref.WeakReference<T>")
);
for (PlatformTestCase platformTestCase : platformTestCases) {
failures += checkToGenericString(platformTestCase.clazz,
platformTestCase.expected);
}
Field f = GenericStringTest.class.getDeclaredField("mixed");
// The expected value includes "<K,V>" rather than
// "<...String,...Integer>" since the Class object rather than
// Type objects is being queried.
failures += checkToGenericString(f.getType(), "java.util.Map<K,V>[]");
f = GenericStringTest.class.getDeclaredField("mixed2");
failures += checkToGenericString(f.getType(), "java.util.Map<K,V>[][]");
for(Class<?> clazz : List.of(GenericStringTest.class,
AnInterface.class,
LocalMap.class,
AnEnum.class,
AnotherEnum.class,
SealedRootClass.class,
SealedRootClass.ChildA.class,
SealedRootClass.ChildB.class,
SealedRootClass.ChildB.GrandChildAB.class,
SealedRootClass.ChildC.class,
SealedRootClass.ChildC.GrandChildACA.class,
SealedRootClass.ChildC.GrandChildACB.class,
SealedRootClass.ChildC.GrandChildACC.class,
SealedRootClass.ChildC.GrandChildACC.GreatGrandChildACCA.class,
SealedRootClass.ChildC.GrandChildACC.GreatGrandChildACCB.class,
SealedRootIntf.class,
SealedRootIntf.ChildA.class,
SealedRootIntf.ChildB.class,
SealedRootIntf.ChildB.GrandChildAB.class,
SealedRootIntf.ChildC.class,
SealedRootIntf.ChildC.GrandChildACA.class,
SealedRootIntf.ChildC.GrandChildACB.class,
SealedRootIntf.ChildC.GrandChildACC.class,
SealedRootIntf.ChildC.GrandChildACC.GreatGrandChildACCA.class,
SealedRootIntf.ChildC.GrandChildACC.GreatGrandChildACCB.class,
SealedRootIntf.IntfA.class,
SealedRootIntf.IntfA.IntfAImpl.class,
SealedRootIntf.IntfB.class,
SealedRootIntf.IntfB.IntfAImpl.class)) {
failures += checkToGenericString(clazz, clazz.getAnnotation(ExpectedGenericString.class).value());
}
if (failures > 0) {
throw new RuntimeException();
}
}
private static int checkToGenericString(Class<?> clazz, String expected) {
String genericString = clazz.toGenericString();
if (!genericString.equals(expected)) {
System.err.printf("Unexpected Class.toGenericString output; expected %n\t'%s',%n got %n\t'%s'.%n",
expected,
genericString);
return 1;
} else
return 0;
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface ExpectedGenericString {
String value();
}
@ExpectedGenericString("abstract interface AnInterface")
strictfp interface AnInterface {}
@ExpectedGenericString("abstract interface LocalMap<K,V>")
interface LocalMap<K,V> {}
@ExpectedGenericString("final enum AnEnum")
enum AnEnum {
FOO;
}
// If an enum class has a specialized enum constant, that is compiled
// by having the enum class as being sealed rather than final. See JLS
// 8.9 Enum Classes.
@ExpectedGenericString("sealed enum AnotherEnum")
enum AnotherEnum {
BAR{};
}
// Test cases for sealed/non-sealed _class_ hierarchy.
@ExpectedGenericString("sealed class SealedRootClass")
sealed class SealedRootClass
permits
SealedRootClass.ChildA,
SealedRootClass.ChildB,
SealedRootClass.ChildC {
@ExpectedGenericString("final class SealedRootClass$ChildA")
final class ChildA extends SealedRootClass {}
@ExpectedGenericString("sealed class SealedRootClass$ChildB")
sealed class ChildB extends SealedRootClass permits SealedRootClass.ChildB.GrandChildAB {
@ExpectedGenericString("final class SealedRootClass$ChildB$GrandChildAB")
final class GrandChildAB extends ChildB {}
}
@ExpectedGenericString("non-sealed class SealedRootClass$ChildC")
non-sealed class ChildC extends SealedRootClass {
// The subclasses of ChildC do not themselves have to be
// sealed, non-sealed, or final.
@ExpectedGenericString("class SealedRootClass$ChildC$GrandChildACA")
class GrandChildACA extends ChildC {}
@ExpectedGenericString("final class SealedRootClass$ChildC$GrandChildACB")
final class GrandChildACB extends ChildC {}
@ExpectedGenericString("sealed class SealedRootClass$ChildC$GrandChildACC")
sealed class GrandChildACC extends ChildC {
@ExpectedGenericString("final class SealedRootClass$ChildC$GrandChildACC$GreatGrandChildACCA")
final class GreatGrandChildACCA extends GrandChildACC {}
@ExpectedGenericString("non-sealed class SealedRootClass$ChildC$GrandChildACC$GreatGrandChildACCB")
non-sealed class GreatGrandChildACCB extends GrandChildACC {}
}
}
}
// Test cases for sealed/non-sealed _interface_ hierarchy.
@ExpectedGenericString("abstract sealed interface SealedRootIntf")
sealed interface SealedRootIntf
permits
SealedRootIntf.ChildA,
SealedRootIntf.ChildB,
SealedRootIntf.ChildC,
SealedRootIntf.IntfA,
SealedRootIntf.IntfB {
@ExpectedGenericString("public static final class SealedRootIntf$ChildA")
final class ChildA implements SealedRootIntf {}
@ExpectedGenericString("public static sealed class SealedRootIntf$ChildB")
sealed class ChildB implements SealedRootIntf permits SealedRootIntf.ChildB.GrandChildAB {
@ExpectedGenericString("final class SealedRootIntf$ChildB$GrandChildAB")
final class GrandChildAB extends ChildB {}
}
@ExpectedGenericString("public static non-sealed class SealedRootIntf$ChildC")
non-sealed class ChildC implements SealedRootIntf {
// The subclasses of ChildC do not themselves have to be
// sealed, non-sealed, or final.
@ExpectedGenericString("class SealedRootIntf$ChildC$GrandChildACA")
class GrandChildACA extends ChildC {}
@ExpectedGenericString("final class SealedRootIntf$ChildC$GrandChildACB")
final class GrandChildACB extends ChildC {}
@ExpectedGenericString("sealed class SealedRootIntf$ChildC$GrandChildACC")
sealed class GrandChildACC extends ChildC {
@ExpectedGenericString("final class SealedRootIntf$ChildC$GrandChildACC$GreatGrandChildACCA")
final class GreatGrandChildACCA extends GrandChildACC {}
@ExpectedGenericString("non-sealed class SealedRootIntf$ChildC$GrandChildACC$GreatGrandChildACCB")
non-sealed class GreatGrandChildACCB extends GrandChildACC {}
}
}
@ExpectedGenericString("public abstract static sealed interface SealedRootIntf$IntfA")
sealed interface IntfA extends SealedRootIntf {
@ExpectedGenericString("public static non-sealed class SealedRootIntf$IntfA$IntfAImpl")
non-sealed class IntfAImpl implements IntfA {}
}
@ExpectedGenericString("public abstract static non-sealed interface SealedRootIntf$IntfB")
non-sealed interface IntfB extends SealedRootIntf {
// Check that non-sealing can be allowed with a second superinterface being sealed.
@ExpectedGenericString("public static non-sealed class SealedRootIntf$IntfB$IntfAImpl")
non-sealed class IntfAImpl implements IntfB, IntfA {}
}
}

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Exercise Class#getModule
* @modules java.desktop
* @run testng GetModuleTest
*/
import java.awt.Component;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
public class GetModuleTest {
private static final Module TEST_MODULE = GetModuleTest.class.getModule();
@DataProvider(name = "testclasses")
public Object[][] testClasses() {
return new Object[][] {
// unnamed module
{ GetModuleTest.class, null },
{ GetModuleTest[].class, null },
{ GetModuleTest[][].class, null },
// should return named module
{ int.class, "java.base" },
{ int[].class, "java.base" },
{ int[][].class, "java.base" },
{ void.class, "java.base" },
{ Object.class, "java.base" },
{ Object[].class, "java.base" },
{ Object[][].class, "java.base" },
{ Component.class, "java.desktop" },
{ Component[].class, "java.desktop" },
{ Component[][].class, "java.desktop" },
};
}
@Test(dataProvider = "testclasses")
public void testGetModule(Class<?> type, String expected) {
Module m = type.getModule();
assertNotNull(m);
if (expected == null) {
assertTrue(m == TEST_MODULE);
} else {
assertEquals(m.getName(), expected);
}
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @requires !vm.graal.enabled
* @modules jdk.attach
* @run main/othervm --limit-modules jdk.attach -Djdk.attach.allowAttachSelf
* GetPackageBootLoaderChildLayer
* @summary Exercise Class.getPackage on a class defined to the boot loader
* but in a module that is in a child layer rather than the boot layer
*/
import com.sun.tools.attach.VirtualMachine;
public class GetPackageBootLoaderChildLayer {
public static void main(String[] args) throws Exception {
// ensure that the java.management module is not in the boot layer
ModuleLayer.boot().findModule("java.management").ifPresent(m -> {
throw new RuntimeException("java.management loaded!!!");
});
// start local JMX agent via the attach mechanism
String vmid = "" + ProcessHandle.current().pid();
VirtualMachine vm = VirtualMachine.attach(vmid);
vm.startLocalManagementAgent();
// check layer, class loader, and Package object
Class<?> clazz = Class.forName("javax.management.MXBean");
if (clazz.getModule().getLayer() == ModuleLayer.boot())
throw new RuntimeException("Module is in boot layer!!!");
ClassLoader loader = clazz.getClassLoader();
if (loader != null)
throw new RuntimeException("Unexpected class loader: " + loader);
Package p = clazz.getPackage();
if (!p.getName().equals("javax.management"))
throw new RuntimeException("Unexpected package " + p);
}
}

View file

@ -0,0 +1,116 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @summary Basic test for Class.getPackage
* @compile Foo.java
* @run testng GetPackageTest
*/
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Properties;
import static org.testng.Assert.*;
public class GetPackageTest {
private static Class<?> fooClass; // definePackage is not called for Foo class
@BeforeTest
public static void loadFooClass() throws ClassNotFoundException {
TestClassLoader loader = new TestClassLoader();
fooClass = loader.loadClass("foo.Foo");
assertEquals(fooClass.getClassLoader(), loader);
}
@DataProvider(name = "testClasses")
public Object[][] testClasses() {
return new Object[][] {
// primitive type, void, array types
{ int.class, null },
{ long[].class, null },
{ Object[][].class, null },
{ void.class, null },
// unnamed package
{ GetPackageTest.class, "" },
// named package
{ fooClass, "foo" },
{ Object.class, "java.lang" },
{ Properties.class, "java.util" },
{ BigInteger.class, "java.math" },
{ Test.class, "org.testng.annotations" },
};
}
@Test(dataProvider = "testClasses")
public void testGetPackage(Class<?> type, String expected) {
Package p = type.getPackage();
if (expected == null) {
assertTrue(p == null);
} else {
assertEquals(p.getName(), expected);
}
}
static class TestClassLoader extends ClassLoader {
public TestClassLoader() {
super();
}
public TestClassLoader(ClassLoader parent) {
super(parent);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Path p = Paths.get(System.getProperty("test.classes", "."));
try {
byte[] bb = Files.readAllBytes(p.resolve("foo/Foo.class"));
return defineClass(name, bb, 0, bb.length);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
protected Class<?> loadClass(String cn, boolean resolve) throws ClassNotFoundException {
if (!cn.equals("foo.Foo"))
return super.loadClass(cn, resolve);
return findClass(cn);
}
}
}

View file

@ -0,0 +1,63 @@
/*
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4891872 4988155
* @summary Check isAnnotation() method
*/
import java.lang.annotation.*;
public class IsAnnotationType {
interface AnnotationPoseur extends Annotation {
}
static int test(Class clazz, boolean expected) {
int status = (clazz.isAnnotation() == expected)?0:1;
if (status == 1) {
System.err.println("Unexpected annotation status for " + clazz);
}
return status;
}
public static void main(String argv[]) {
int failures = 0;
failures += test(String.class, false);
failures += test(Enum.class, false);
failures += test(java.math.RoundingMode.class, false);
// Classes in java.lang.annotation
failures += test(Annotation.class, false);
failures += test(Retention.class, true);
failures += test(RetentionPolicy.class, false);
failures += test(Target.class, true);
failures += test(AnnotationPoseur.class, false);
if (failures > 0) {
throw new RuntimeException("Unexpected annotation " +
"status detected.");
}
}
}

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4891872 4989735 4990789 5020490
* @summary Check isEnum() method
*/
import java.lang.annotation.*;
public class IsEnum {
static int test(Class<?> clazz, boolean expected) {
int status = (clazz.isEnum() == expected) ? 0 : 1;
if (status == 1) {
System.err.println("Unexpected enum status for " + clazz);
}
return status;
}
public static void main(String... argv) {
int failures = 0;
failures += test(IsEnum.class, false);
failures += test(String.class, false);
failures += test(Enum.class, false);
failures += test(EnumPoseur.class, false);
failures += test(java.math.RoundingMode.class, true);
// Classes in java.lang.annotation
failures += test(Annotation.class, false);
failures += test(ElementType.class, true);
failures += test(Retention.class, false);
failures += test(RetentionPolicy.class, true);
failures += test(Target.class, false);
// A class for a specialized enum constant isn't itself an enum
failures += test(SpecialEnum.class, true);
failures += test(SpecialEnum.RED.getClass(), false);
failures += test(SpecialEnum.GREEN.getClass(), true);
if (failures > 0) {
throw new RuntimeException("Unexpected enum status detected.");
}
}
}
enum SpecialEnum {
RED {
String special() {return "riding hood";}
},
GREEN;
String special() {return "how was my valley";}
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 5012133
* @summary Check Class.isSynthetic method
*/
import java.lang.reflect.*;
public class IsSynthetic {
static class NestedClass {
}
static int test(Class<?> clazz, boolean expected) {
if (clazz.isSynthetic() == expected)
return 0;
else {
System.err.println("Unexpected synthetic status for " +
clazz.getName() + " expected: " + expected +
" got: " + (!expected));
return 1;
}
}
public static void main(String argv[]) {
int failures = 0;
class LocalClass {}
Cloneable clone = new Cloneable() {};
failures += test(IsSynthetic.class, false);
failures += test(java.lang.String.class, false);
failures += test(LocalClass.class, false);
failures += test(NestedClass.class, false);
failures += test(clone.getClass(), false);
for(Constructor c: Tricky.class.getDeclaredConstructors()) {
Class<?>[] paramTypes = c.getParameterTypes();
if (paramTypes.length > 0) {
System.out.println("Testing class that should be synthetic.");
for(Class paramType: paramTypes) {
failures += test(paramType, true);
}
}
}
if (failures != 0)
throw new RuntimeException("Test failed with " + failures + " failures.");
}
}
class Tricky {
private Tricky() {}
public static class Nested {
Tricky t = new Tricky();
}
}

View file

@ -0,0 +1,101 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8281671
* @summary Checks on various "getFooName" methods of java.lang.Class
*/
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class NameTest {
public static void main(String... args) {
testCanonicalName();
testSimpleName();
}
private static void testCanonicalName() {
class LocalClass {} // Local class; no canonical name
Object o = new Object() {}; // Anonymous class; no canonical name
Object[] objectArray = {};
Map<Class<?>, String> expectedCanonicalName = new HashMap<>();
expectedCanonicalName.put(LocalClass.class, null);
expectedCanonicalName.put(o.getClass(), null);
// If a component type doesn't have a canonical name, neither
// does an array of that type.
expectedCanonicalName.put(LocalClass.class.arrayType(), null);
expectedCanonicalName.put(o.getClass().arrayType(), null);
expectedCanonicalName.put(int.class, "int");
expectedCanonicalName.put(Object.class, "java.lang.Object");
expectedCanonicalName.put(objectArray.getClass(), "java.lang.Object[]");
for (var entry : expectedCanonicalName.entrySet()) {
var key = entry.getKey();
var expectedName = entry.getValue();
String canonicalName = key.getCanonicalName();
if (!Objects.equals(canonicalName, expectedName)) {
System.err.println("Unexpected canonical name '" +
canonicalName + "' found for " +
key + ", expected " + expectedName);
throw new RuntimeException();
}
}
}
private static void testSimpleName() {
class ALocalClass {} // Local class
Object o = new Object() {}; // Anonymous class, empty simple name
Object[] objectArray = {};
Map<Class<?>, String> expectedSimpleName = new HashMap<>();
expectedSimpleName.put(ALocalClass.class, "ALocalClass");
expectedSimpleName.put(o.getClass(), "");
expectedSimpleName.put(ALocalClass.class.arrayType(), "ALocalClass[]");
expectedSimpleName.put(o.getClass().arrayType(), "[]");
expectedSimpleName.put(int.class, "int");
expectedSimpleName.put(Object.class, "Object");
expectedSimpleName.put(objectArray.getClass(), "Object[]");
for (var entry : expectedSimpleName.entrySet()) {
var key = entry.getKey();
var expectedName = entry.getValue();
String simpleName = key.getSimpleName();
if (!Objects.equals(simpleName, expectedName)) {
System.err.println("Unexpected simple name '" +
simpleName + "' found for " +
key + ", expected " + expectedName);
throw new RuntimeException();
}
}
}
}

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8371953
* @summary Check null argument behaviors for java.lang.Class APIs.
* @run junit NullBehaviorTest
*/
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class NullBehaviorTest {
@Test
void nullChecks() {
assertThrows(NullPointerException.class, () -> Class.forName(null));
assertDoesNotThrow(() -> Class.forName("java.lang.Object", false, null));
assertThrows(NullPointerException.class, () -> Class.forName(null, false, null));
assertThrows(NullPointerException.class, () -> Class.forName(null, "java.lang.Object"));
assertThrows(NullPointerException.class, () -> Class.forName(Object.class.getModule(), null));
assertThrows(NullPointerException.class, () -> Class.forPrimitiveName(null));
assertFalse(Object.class.isInstance(null));
assertThrows(NullPointerException.class, () -> Object.class.isAssignableFrom(null));
assertThrows(NullPointerException.class, () -> Object.class.getField(null));
assertThrows(NullPointerException.class, () -> Object.class.getDeclaredField(null));
assertThrows(NullPointerException.class, () -> Object.class.getMethod(null));
assertThrows(NullPointerException.class, () -> Object.class.getDeclaredMethod(null));
assertDoesNotThrow(() -> Object.class.getMethod("hashCode", (Class<?>[]) null));
assertDoesNotThrow(() -> Object.class.getDeclaredMethod("hashCode", (Class<?>[]) null));
assertThrows(NoSuchMethodException.class, () -> Object.class.getMethod("hashCode", new Class[]{null}));
assertThrows(NoSuchMethodException.class, () -> Object.class.getDeclaredMethod("hashCode", new Class[]{null}));
assertDoesNotThrow(() -> Object.class.getConstructor((Class<?>[]) null));
assertDoesNotThrow(() -> Object.class.getDeclaredConstructor((Class<?>[]) null));
assertThrows(NoSuchMethodException.class, () -> Object.class.getConstructor(new Class[]{null}));
assertThrows(NoSuchMethodException.class, () -> Object.class.getDeclaredConstructor(new Class[]{null}));
assertThrows(NullPointerException.class, () -> Object.class.getResourceAsStream(null));
assertThrows(NullPointerException.class, () -> Object.class.getResource(null));
assertDoesNotThrow(() -> Object.class.cast(null));
assertThrows(NullPointerException.class, () -> Object.class.asSubclass(null));
assertThrows(NullPointerException.class, () -> Object.class.isNestmateOf(null));
assertThrows(NullPointerException.class, () -> int.class.isNestmateOf(null));
}
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8334394
* @summary ensure there is no race condition in Class::protectionDomain
* @run main/othervm ProtectionDomainRace
*/
import javax.security.auth.Subject;
import java.security.PrivilegedAction;
/**
* Without the code fix, this test would fail with
* java.lang.AssertionError: sun.security.util.ResourcesMgr (PD)
* at java.base/java.lang.invoke.MethodHandleImpl$BindCaller.checkInjectedInvoker(MethodHandleImpl.java:1209)
* at java.base/java.lang.invoke.MethodHandleImpl$BindCaller.makeInjectedInvoker(MethodHandleImpl.java:1110)
* at java.base/java.lang.invoke.MethodHandleImpl$BindCaller$1.computeValue(MethodHandleImpl.java:1117)
* at java.base/java.lang.invoke.MethodHandleImpl$BindCaller$1.computeValue(MethodHandleImpl.java:1114)
* at java.base/java.lang.ClassValue.getFromHashMap(ClassValue.java:229)
* at java.base/java.lang.ClassValue.getFromBackup(ClassValue.java:211)
* at java.base/java.lang.ClassValue.get(ClassValue.java:117)
* at java.base/java.lang.invoke.MethodHandleImpl$BindCaller.bindCallerWithInjectedInvoker(MethodHandleImpl.java:1089)
* at java.base/java.lang.invoke.MethodHandleImpl$BindCaller.bindCaller(MethodHandleImpl.java:1077)
* at java.base/java.lang.invoke.MethodHandleImpl.bindCaller(MethodHandleImpl.java:1032)
* at java.base/java.lang.invoke.MethodHandles$Lookup.maybeBindCaller(MethodHandles.java:4149)
* at java.base/java.lang.invoke.MethodHandles$Lookup.getDirectMethodCommon(MethodHandles.java:4133)
* at java.base/java.lang.invoke.MethodHandles$Lookup.getDirectMethodNoSecurityManager(MethodHandles.java:4077)
* at java.base/java.lang.invoke.MethodHandles$Lookup.getDirectMethodForConstant(MethodHandles.java:4326)
* at java.base/java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:4274)
* at java.base/java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:628)
* at java.base/sun.security.util.ResourcesMgr.getBundle(ResourcesMgr.java:54)
* at java.base/sun.security.util.ResourcesMgr.getString(ResourcesMgr.java:40)
* at java.base/javax.security.auth.Subject.doAs(Subject.java:517)
* ...
* as the Class::protectionDomain might assign different objects to the (original) allPermDomain field.
*/
public class ProtectionDomainRace {
private static volatile Throwable failed = null;
public static void main(String[] args) throws Throwable {
PrivilegedAction<?> pa = () -> null;
Thread[] threads = new Thread[100];
for (int i = 0; i < 100; i++) {
threads[i] = new Thread(() -> {
try {
Subject.doAs(null, pa);
} catch (Throwable t) {
failed = t;
}
});
threads[i].start();
}
for (int i = 0; i < 100; i++) {
threads[i].join();
}
if (failed != null) {
throw failed;
}
}
}

View file

@ -0,0 +1,199 @@
/*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This is not a regression test, but a micro-benchmark.
*
* I have run this as follows:
*
* repeat 5 for f in -client -server; do mergeBench dolphin . jr -dsa -da $f TypeCheckMicroBenchmark.java; done
*
*
* @author Martin Buchholz
*/
import java.util.*;
public class TypeCheckMicroBenchmark {
abstract static class Job {
private final String name;
Job(String name) { this.name = name; }
String name() { return name; }
abstract void work() throws Throwable;
}
private static void collectAllGarbage() {
final java.util.concurrent.CountDownLatch drained
= new java.util.concurrent.CountDownLatch(1);
try {
System.gc(); // enqueue finalizable objects
new Object() { protected void finalize() {
drained.countDown(); }};
System.gc(); // enqueue detector
drained.await(); // wait for finalizer queue to drain
System.gc(); // cleanup finalized objects
} catch (InterruptedException e) { throw new Error(e); }
}
/**
* Runs each job for long enough that all the runtime compilers
* have had plenty of time to warm up, i.e. get around to
* compiling everything worth compiling.
* Returns array of average times per job per run.
*/
private static long[] time0(Job ... jobs) throws Throwable {
final long warmupNanos = 10L * 1000L * 1000L * 1000L;
long[] nanoss = new long[jobs.length];
for (int i = 0; i < jobs.length; i++) {
collectAllGarbage();
long t0 = System.nanoTime();
long t;
int j = 0;
do { jobs[i].work(); j++; }
while ((t = System.nanoTime() - t0) < warmupNanos);
nanoss[i] = t/j;
}
return nanoss;
}
private static void time(Job ... jobs) throws Throwable {
long[] warmup = time0(jobs); // Warm up run
long[] nanoss = time0(jobs); // Real timing run
long[] milliss = new long[jobs.length];
double[] ratios = new double[jobs.length];
final String nameHeader = "Method";
final String millisHeader = "Millis";
final String ratioHeader = "Ratio";
int nameWidth = nameHeader.length();
int millisWidth = millisHeader.length();
int ratioWidth = ratioHeader.length();
for (int i = 0; i < jobs.length; i++) {
nameWidth = Math.max(nameWidth, jobs[i].name().length());
milliss[i] = nanoss[i]/(1000L * 1000L);
millisWidth = Math.max(millisWidth,
String.format("%d", milliss[i]).length());
ratios[i] = (double) nanoss[i] / (double) nanoss[0];
ratioWidth = Math.max(ratioWidth,
String.format("%.3f", ratios[i]).length());
}
String format = String.format("%%-%ds %%%dd %%%d.3f%%n",
nameWidth, millisWidth, ratioWidth);
String headerFormat = String.format("%%-%ds %%%ds %%%ds%%n",
nameWidth, millisWidth, ratioWidth);
System.out.printf(headerFormat, "Method", "Millis", "Ratio");
// Print out absolute and relative times, calibrated against first job
for (int i = 0; i < jobs.length; i++)
System.out.printf(format, jobs[i].name(), milliss[i], ratios[i]);
}
private static String keywordValue(String[] args, String keyword) {
for (String arg : args)
if (arg.startsWith(keyword))
return arg.substring(keyword.length() + 1);
return null;
}
private static int intArg(String[] args, String keyword, int defaultValue) {
String val = keywordValue(args, keyword);
return val == null ? defaultValue : Integer.parseInt(val);
}
private static java.util.regex.Pattern patternArg(String[] args,
String keyword) {
String val = keywordValue(args, keyword);
return val == null ? null : java.util.regex.Pattern.compile(val);
}
private static Job[] filter(java.util.regex.Pattern filter,
Job[] jobs) {
if (filter == null) return jobs;
Job[] newJobs = new Job[jobs.length];
int n = 0;
for (Job job : jobs)
if (filter.matcher(job.name()).find())
newJobs[n++] = job;
// Arrays.copyOf not available in JDK 5
Job[] ret = new Job[n];
System.arraycopy(newJobs, 0, ret, 0, n);
return ret;
}
/**
* Usage: [iterations=N] [size=N] [filter=REGEXP]
*/
public static void main(String[] args) throws Throwable {
final int iterations = intArg(args, "iterations", 30000);
final int size = intArg(args, "size", 1000);
final java.util.regex.Pattern filter
= patternArg(args, "filter");
final List<Integer> list = new ArrayList<Integer>();
final Random rnd = new Random();
for (int i = 0; i < size; i++)
list.add(rnd.nextInt());
final Class klazz = Integer.class;
final Job[] jobs = {
new Job("toArray(T[])") { void work() {
Object[] a = new Integer[0];
for (int i = 0; i < iterations; i++) {
try { list.toArray(a); }
catch (ArrayStoreException ase) {
throw new ClassCastException(); }}}},
new Job("isInstance") { void work() {
for (int i = 0; i < iterations; i++) {
for (Object x : list.toArray())
if (! (x != null && klazz.isInstance(x)))
throw new ClassCastException(); }}},
new Job("Class.cast") { void work() {
for (int i = 0; i < iterations; i++) {
for (Object x : list.toArray())
klazz.cast(x); }}},
new Job("write into array") { void work() {
Object[] a = new Integer[1];
for (int i = 0; i < iterations; i++) {
for (Object x : list.toArray()) {
try { a[0] = x; }
catch (ArrayStoreException unused) {
throw new ClassCastException(); }}}}},
new Job("write into dynamic array") { void work() {
for (int i = 0; i < iterations; i++) {
for (Object x : list.toArray()) {
Object[] a = (Object[])
java.lang.reflect.Array.newInstance(klazz, 1);
try { a[0] = x; }
catch (ArrayStoreException unused) {
throw new ClassCastException(); }}}}}
};
time(filter(filter, jobs));
}
}

View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 5030212
* @summary please add a typesafe cast for Class<?> types
* @author gafter
*
* @compile -Xlint:unchecked -Werror BasicUnit.java
* @run main BasicUnit
*/
interface Int {
void main();
}
class MyInt implements Int {
public void main() {
System.out.println("Hello, world!");
}
}
public class BasicUnit {
static <T extends Int> T factory(Class<T> c) throws Throwable {
return c.newInstance();
}
public static void main(String[] args) throws Throwable {
factory(Class.forName("MyInt").asSubclass(Int.class)).main();
}
}

View file

@ -0,0 +1,76 @@
/*
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8170595
* @summary Checks Class.isAnonymousClass, isMemberClass and isLocalClass
* attributes
*/
public class ClassAttributesTest {
class NestedClass {}
static int test(Class<?> clazz, boolean anonymous, boolean local, boolean member) {
if (clazz.isAnonymousClass() != anonymous) {
System.err.println("Unexpected isAnonymousClass value for " +
clazz.getName() + " expected: " + anonymous +
" got: " + (!anonymous));
return 1;
}
if (clazz.isLocalClass() != local) {
System.err.println("Unexpected isLocalClass value for " +
clazz.getName() + " expected: " + local +
" got: " + (!local));
return 1;
}
if (clazz.isMemberClass() != member) {
System.err.println("Unexpected isMemberClass status for " +
clazz.getName() + " expected: " + member +
" got: " + (!member));
return 1;
}
return 0;
}
public static void main(String argv[]) {
int failures = 0;
class LocalClass {}
Cloneable clone = new Cloneable() {};
Runnable lambda = () -> System.out.println("run");
failures += test(ClassAttributesTest.class, false, false, false);
failures += test(NestedClass.class, false, false, true);
failures += test(LocalClass.class, false, true, false);
failures += test(clone.getClass(), true, false, false);
// Lambdas may be hidden classes, but are named, non-local classes
// in this sense
failures += test(lambda.getClass(), false, false, false);
if (failures != 0)
throw new RuntimeException("Test failed with " + failures + " failures.");
}
}

View file

@ -0,0 +1,177 @@
/*
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8310242 8328874
* @run junit ForNameNames
* @summary Verify class names for Class.forName
*/
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.*;
public class ForNameNames {
//Max length in Modified UTF-8 bytes for class names.
private static final int JAVA_CLASSNAME_MAX_LEN = 65535;
private static final String ONE_BYTE = "A"; // 1-byte UTF-8
private static final String TWO_BYTE = "\u0100"; // 2-byte UTF-8
private static final String THREE_BYTE = "\u2600"; // 3-byte UTF-8
private static final String ERR_MSG_IN_CORE = "Class name length exceeds limit of"; // check in corelib
private static final String ERR_MSG_IN_JVM = "Class name exceeds maximum length"; // check in jvm
static class Inner {}
static Stream<Arguments> testCases() {
return Stream.of(
Arguments.of("java.lang.String", String.class),
Arguments.of("[Ljava.lang.String;", String[].class),
Arguments.of("ForNameNames$Inner", Inner.class),
Arguments.of("[LForNameNames$Inner;", Inner[].class),
Arguments.of("[[I", int[][].class)
);
}
/*
* Test 1-arg and 3-arg Class::forName. Class::getName on the returned
* Class object returns the name passed to Class::forName.
*/
@ParameterizedTest
@MethodSource("testCases")
void testForName(String cn, Class<?> expected) throws ClassNotFoundException {
ClassLoader loader = ForNameNames.class.getClassLoader();
Class<?> c1 = Class.forName(cn, false, loader);
assertEquals(expected, c1);
assertEquals(cn, c1.getName());
Class<?> c2 = Class.forName(cn);
assertEquals(expected, c2);
assertEquals(cn, c2.getName());
}
static Stream<Arguments> invalidNames() {
return Stream.of(
Arguments.of("I"), // primitive type
Arguments.of("int[]"), // fully-qualified name of int array
Arguments.of("ForNameNames.Inner"), // fully-qualified name of nested type
Arguments.of("[java.lang.String"), // missing L and ;
Arguments.of("[Ljava.lang.String"), // missing ;
Arguments.of("[Ljava/lang/String;") // type descriptor
);
}
@ParameterizedTest
@MethodSource("invalidNames")
void testInvalidNames(String cn) {
ClassLoader loader = ForNameNames.class.getClassLoader();
assertThrows(ClassNotFoundException.class, () -> Class.forName(cn, false, loader));
}
@Test
void testModule() {
// Class.forName(Module, String) does not allow class name for array types
Class<?> c = Class.forName(Object.class.getModule(), "[Ljava.lang.String;");
assertNull(c);
}
static Stream<Arguments> validLen() {
return Stream.of(
// 1-byte character
Arguments.of(ONE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN - 1)),
Arguments.of(ONE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN)),
Arguments.of(ONE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 3 - 1)),
Arguments.of(ONE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 3)),
Arguments.of(ONE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 3 + 1)),
// 2-byte characters
Arguments.of(TWO_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 2)),
Arguments.of(TWO_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 6)),
Arguments.of(TWO_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 6 + 1)),
// 3-byte characters
Arguments.of(THREE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 3 - 1)),
Arguments.of(THREE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 3)),
Arguments.of(THREE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 9)),
Arguments.of(THREE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 9 + 1))
);
}
/*
* Test class name length handling in 1-arg and 3-arg Class::forName
* with valid length.
*/
@ParameterizedTest
@MethodSource("validLen")
void testValidLen(String cn) {
ClassLoader loader = ForNameNames.class.getClassLoader();
// 3-arg Class.forName
ClassNotFoundException ex = assertThrows(ClassNotFoundException.class,
() -> Class.forName(cn, false, loader));
assertFalse(ex.getMessage().contains(ERR_MSG_IN_CORE)
|| ex.getMessage().contains(ERR_MSG_IN_JVM),
"Unexpected exception message");
// 1-arg Class.forName
ex = assertThrows(ClassNotFoundException.class,
() -> Class.forName(cn));
assertFalse(ex.getMessage().contains(ERR_MSG_IN_CORE)
|| ex.getMessage().contains(ERR_MSG_IN_JVM),
"Unexpected exception message");
}
static Stream<Arguments> invalidLen() {
return Stream.of(
// 1-byte characters over the limit
Arguments.of(ONE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN + 1)),
// 2-byte characters over the limit
Arguments.of(TWO_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 2 + 1)),
// 3-byte characters over the limit
Arguments.of(THREE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 3 + 1))
);
}
/*
* Test class name length handling in 1-arg and 3-arg Class::forName
* with invalid (too long) length.
*/
@ParameterizedTest
@MethodSource("invalidLen")
void testInvalidLen(String cn) {
ClassLoader loader = ForNameNames.class.getClassLoader();
// 3-arg Class.forName
ClassNotFoundException ex = assertThrows(ClassNotFoundException.class,
() -> Class.forName(cn, false, loader));
assertTrue(ex.getMessage().contains(ERR_MSG_IN_CORE),
"Unexpected exception message");
// 1-arg Class.forName
ex = assertThrows(ClassNotFoundException.class,
() -> Class.forName(cn));
assertTrue(ex.getMessage().contains(ERR_MSG_IN_CORE),
"Unexpected exception message");
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4131701
@summary This is a basic sanity test for the Class.forName
variant that the 'whether-initialize' arg.
*/
class x123 {
static {
InitArg.x123Initialized = true;
}
}
public class InitArg {
public static boolean x123Initialized = false;
public static void main(String[] args) throws Exception {
Class c = Class.forName("x123", false,
InitArg.class.getClassLoader());
if (x123Initialized) {
throw new Exception("forName should not run initializer");
}
Class d = Class.forName("x123", true,
InitArg.class.getClassLoader());
if (!x123Initialized) {
throw new Exception("forName not running initializer");
}
}
}

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4104861
@summary forName is accepting methods with slashes
@author James Bond/007
*/
public class InvalidNameWithSlash {
public static void main(String[] args) throws Exception {
boolean exceptionOccurred = false;
try {
Class c = Class.forName("java/lang.Object");
} catch (Exception e) {
exceptionOccurred = true;
}
if (!exceptionOccurred) {
throw new Exception("forName accepting names with slashes?");
}
}
}

View file

@ -0,0 +1,160 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/*
* @test
* @bug 4952558
* @library /test/lib
* @run testng/othervm NonJavaNames
* @summary Verify names that aren't legal Java names are accepted by forName.
*/
public class NonJavaNames {
public static class Baz {
public Baz(){}
}
public static interface myInterface {
}
NonJavaNames.myInterface create() {
// With target 1.5, this class's name will include a '+'
// instead of a '$'.
class Baz2 implements NonJavaNames.myInterface {
public Baz2() { }
}
return new Baz2();
}
private static final String SRC_DIR = System.getProperty("test.src");
private static final Path TEST_SRC = Path.of(SRC_DIR, "classes");
private static final Path TEST_CLASSES = Path.of(System.getProperty("test.classes", "."));
@BeforeClass
public void createInvalidNameClasses() throws IOException {
Path hyphenPath = TEST_SRC.resolve("hyphen.class");
Path commaPath = TEST_SRC.resolve("comma.class");
Path periodPath = TEST_SRC.resolve("period.class");
Path leftsquarePath = TEST_SRC.resolve("left-square.class");
Path rightsquarePath = TEST_SRC.resolve("right-square.class");
Path plusPath = TEST_SRC.resolve("plus.class");
Path semicolonPath = TEST_SRC.resolve("semicolon.class");
Path zeroPath = TEST_SRC.resolve("0.class");
Path threePath = TEST_SRC.resolve("3.class");
Path zadePath = TEST_SRC.resolve("Z.class");
Path dhyphenPath = TEST_CLASSES.resolve("-.class");
Path dcommaPath = TEST_CLASSES.resolve(",.class");
Path dperiodPath = TEST_CLASSES.resolve("..class");
Path dleftsquarePath = TEST_CLASSES.resolve("[.class");
Path drightsquarePath = TEST_CLASSES.resolve("].class");
Path dplusPath = TEST_CLASSES.resolve("+.class");
Path dsemicolonPath = TEST_CLASSES.resolve(";.class");
Path dzeroPath = TEST_CLASSES.resolve("0.class");
Path dthreePath = TEST_CLASSES.resolve("3.class");
Path dzadePath = TEST_CLASSES.resolve("Z.class");
Files.copy(hyphenPath, dhyphenPath, REPLACE_EXISTING);
Files.copy(commaPath, dcommaPath, REPLACE_EXISTING);
Files.copy(periodPath, dperiodPath, REPLACE_EXISTING);
Files.copy(leftsquarePath, dleftsquarePath, REPLACE_EXISTING);
Files.copy(rightsquarePath, drightsquarePath, REPLACE_EXISTING);
Files.copy(plusPath, dplusPath, REPLACE_EXISTING);
Files.copy(semicolonPath, dsemicolonPath, REPLACE_EXISTING);
Files.copy(zeroPath, dzeroPath, REPLACE_EXISTING);
Files.copy(threePath, dthreePath, REPLACE_EXISTING);
Files.copy(zadePath, dzadePath, REPLACE_EXISTING);
}
@Test
public void testForNameReturnsSameClass() throws ClassNotFoundException {
NonJavaNames.Baz bz = new NonJavaNames.Baz();
String name;
if (Class.forName(name=bz.getClass().getName()) != NonJavaNames.Baz.class) {
System.err.println("Class object from forName does not match object.class.");
System.err.println("Failures for class ``" + name + "''.");
throw new RuntimeException();
}
NonJavaNames.myInterface bz2 = (new NonJavaNames()).create();
if (Class.forName(name=bz2.getClass().getName()) != bz2.getClass()) {
System.err.println("Class object from forName does not match getClass.");
System.err.println("Failures for class ``" + name + "''.");
throw new RuntimeException();
}
}
@Test(dataProvider = "goodNonJavaClassNames")
public void testGoodNonJavaClassNames(String name) throws ClassNotFoundException {
System.out.println("Testing good class name ``" + name + "''");
Class.forName(name);
}
@Test(dataProvider = "badNonJavaClassNames")
public void testBadNonJavaClassNames(String name) {
System.out.println("Testing bad class name ``" + name + "''");
try {
Class.forName(name);
} catch (ClassNotFoundException e) {
// Expected behavior
return;
}
throw new RuntimeException("Bad class name ``" + name + "'' accepted.");
}
@DataProvider(name = "goodNonJavaClassNames")
Object[][] getGoodNonJavaClassNames() {
return new Object[][] {
{","},
{"+"},
{"-"},
{"0"},
{"3"},
// ":", These names won't work under windows.
// "<",
// ">",
{"Z"},
{"]"}
};
}
@DataProvider(name = "badNonJavaClassNames")
Object[][] getBadNonJavaClassNames() {
return new Object[][] {
{";"},
{"["},
{"."}
};
}
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public class Container {
public Container(MissingClass m) {}
public Container() {
this(new MissingClass() {});
}
}

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public class MissingClass {}

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Path;
import java.nio.file.Paths;
/*
* @test
* @bug 8231924 8233091 8233272
* @summary Confirm load (but not link) behavior of Class.forName()
* @library /test/lib
*
* @compile MissingClass.java Container.java
*
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar classes.jar Container Container$1
*
* @run main/othervm NonLinking init
* @run main/othervm NonLinking load
*/
/*
* The @compile and '@main ClassFileInstaller' tasks above create a classes.jar
* file containing the .class file for Container, but not MissingClass.
*/
public class NonLinking {
public static void main(String[] args) throws Throwable {
Path jarPath = Paths.get("classes.jar");
URL url = jarPath.toUri().toURL();
URLClassLoader ucl1 = new URLClassLoader("UCL1",
new URL[] { url },
null); // Don't delegate
switch(args[0]) {
case "init":
try {
// Trying to initialize Container without MissingClass -> NCDFE
Class.forName("Container", true, ucl1);
throw new RuntimeException("Missed expected NoClassDefFoundError");
} catch (NoClassDefFoundError expected) {
final String CLASSNAME = "MissingClass";
Throwable cause = expected.getCause();
if (!cause.getMessage().contains(CLASSNAME)) {
throw new RuntimeException("Cause of NoClassDefFoundError does not contain \"" + CLASSNAME + "\"", cause);
}
}
break;
case "load":
// Loading (but not linking) Container will succeed.
// Before 8233091, this fails with NCDFE due to linking.
Class.forName("Container", false, ucl1);
break;
default:
throw new RuntimeException("Unknown command: " + args[0]);
}
}
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Source used to generated primordial class file for NonJavaNames
* test.
*/
public class Z {
public static void main(String argv[]) {
System.out.println("Hello world.");
}
}

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public class Class1 {}

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public class Class2 {}

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public class Class3 {}

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
public class Class4 {}

View file

@ -0,0 +1,129 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 7044282
* @build Class1 Class2 Class3 Class4
* @run main ExceedMaxDim
* @summary Make sure you can't get an array class of dimension > 255.
*/
// Class1, Class2, Class3 and Class4 should not have been loaded prior to the
// calls to forName
public class ExceedMaxDim {
//0123456789012345678901234567890123456789
private String brackets = "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" +
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" +
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" +
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" +
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" +
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" +
"[[[[[[[[[[[[[[";
private String name254 = brackets + "Ljava.lang.String;";
private String name255 = "[" + name254;
private String name256 = "[" + name255;
private String name1 = "[Ljava.lang.String;";
private String bigName;
private int error = 0;
private static final ClassLoader IMPLICIT_LOADER = null;
public ExceedMaxDim() {
super();
StringBuilder sb = new StringBuilder(Short.MAX_VALUE + 50);
for (int i = 0; i < Short.MAX_VALUE + 20; i++)
sb.append('[');
sb.append("Ljava.lang.String;");
bigName = sb.toString();
if (name256.lastIndexOf('[') != 255) // 256:th [
throw new RuntimeException("Test broken");
}
public static void main(String[] args) throws Exception {
ExceedMaxDim test = new ExceedMaxDim();
test.testImplicitLoader();
test.testOtherLoader();
if (test.error != 0)
throw new RuntimeException("Test failed, was able to create array with dim > 255." +
" See log for details.");
}
private void testImplicitLoader() throws Exception {
// These four should succeed
assertSucceedForName(name1, IMPLICIT_LOADER);
assertSucceedForName(name254, IMPLICIT_LOADER);
assertSucceedForName(name255, IMPLICIT_LOADER);
assertSucceedForName(brackets + "[LClass1;", IMPLICIT_LOADER);
// The following three should fail
assertFailForName(name256, IMPLICIT_LOADER);
assertFailForName(bigName, IMPLICIT_LOADER);
assertFailForName(brackets + "[[LClass2;", IMPLICIT_LOADER);
}
private void testOtherLoader() throws Exception {
ClassLoader cl = ExceedMaxDim.class.getClassLoader();
// These four should succeed
assertSucceedForName(name1, cl);
assertSucceedForName(name254,cl);
assertSucceedForName(name255, cl);
assertSucceedForName(brackets + "[LClass3;", cl);
// The following three should fail
assertFailForName(name256, cl);
assertFailForName(bigName, cl);
assertFailForName(brackets + "[[Class4;", cl);
}
private void assertFailForName(String name, ClassLoader cl) {
Class<?> c;
try {
if (cl == null)
c = Class.forName(name);
else
c = Class.forName(name, true, cl);
error++;
System.err.println("ERROR: could create " + c);
} catch (ClassNotFoundException e) {
;// ok
}
}
private void assertSucceedForName(String name, ClassLoader cl) {
Class<?> c;
try {
if (cl == null)
c = Class.forName(name);
else
c = Class.forName(name, true, cl);
} catch (ClassNotFoundException e) {
error++;
System.err.println("ERROR: could not create " + name);
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,134 @@
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.stream.Stream;
import jdk.test.lib.util.FileUtils;
import jdk.test.lib.compiler.CompilerUtils;
import static jdk.test.lib.process.ProcessTools.*;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import static org.testng.Assert.assertTrue;
/**
* @test
* @bug 8087335
* @summary Tests for Class.forName(Module,String)
* @library /test/lib
* @modules jdk.compiler
* @build jdk.test.lib.Platform
* jdk.test.lib.util.FileUtils
* jdk.test.lib.compiler.CompilerUtils
* jdk.test.lib.process.ProcessTools
* TestDriver TestMain TestLayer
* @run testng TestDriver
*/
public class TestDriver {
private static final String TEST_SRC =
Paths.get(System.getProperty("test.src")).toString();
private static final String TEST_CLASSES =
Paths.get(System.getProperty("test.classes")).toString();
private static final Path MOD_SRC_DIR = Paths.get(TEST_SRC, "src");
private static final Path MOD_DEST_DIR = Paths.get("mods");
private static final String[] modules = new String[] {"m1", "m2"};
/**
* Compiles all modules used by the test.
*/
@BeforeClass
public void setup() throws Exception {
assertTrue(CompilerUtils.compile(
MOD_SRC_DIR, MOD_DEST_DIR,
"--module-source-path",
MOD_SRC_DIR.toString()));
copyDirectories(MOD_DEST_DIR.resolve("m1"), Paths.get("mods1"));
copyDirectories(MOD_DEST_DIR.resolve("m2"), Paths.get("mods2"));
}
@Test
public void test() throws Exception {
String[] options = new String[] {
"-cp", TEST_CLASSES,
"--module-path", MOD_DEST_DIR.toString(),
"--add-modules", String.join(",", modules),
"-m", "m2/p2.test.Main"
};
runTest(options);
}
@Test
public void testUnnamedModule() throws Exception {
String[] options = new String[] {
"-cp", TEST_CLASSES,
"--module-path", MOD_DEST_DIR.toString(),
"--add-modules", String.join(",", modules),
"TestMain"
};
runTest(options);
}
@Test
public void testLayer() throws Exception {
String[] options = new String[] {
"-cp", TEST_CLASSES,
"TestLayer"
};
runTest(options);
}
private void runTest(String[] options) throws Exception {
assertTrue(executeTestJava(options)
.outputTo(System.out)
.errorTo(System.err)
.getExitValue() == 0);
}
private void copyDirectories(Path source, Path dest) throws IOException {
if (Files.exists(dest))
FileUtils.deleteFileTreeWithRetry(dest);
Files.walk(source, Integer.MAX_VALUE)
.filter(Files::isRegularFile)
.forEach(p -> {
try {
Path to = dest.resolve(source.relativize(p));
Files.createDirectories(to.getParent());
Files.copy(p, to);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
}
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.lang.module.Configuration;
import java.lang.module.ModuleFinder;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;
public class TestLayer {
private static final Path MODS_DIR = Paths.get("mods");
private static final Set<String> modules = Set.of("m1", "m2");
public static void main(String[] args) throws Exception {
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
Configuration parent = ModuleLayer.boot().configuration();
Configuration cf = parent.resolveAndBind(ModuleFinder.of(),
finder,
modules);
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl);
Module m1 = layer.findModule("m1").get();
Module m2 = layer.findModule("m2").get();
// find exported and non-exported class from a named module
findClass(m1, "p1.A");
findClass(m1, "p1.internal.B");
findClass(m2, "p2.C");
// find class from unnamed module
ClassLoader ld = TestLayer.class.getClassLoader();
findClass(ld.getUnnamedModule(), "TestDriver");
// check if clinit should not be initialized
// compile without module-path; so use reflection
Class<?> c = Class.forName(m1, "p1.Initializer");
Method m = c.getMethod("isInited");
Boolean isClinited = (Boolean) m.invoke(null);
if (isClinited.booleanValue()) {
throw new RuntimeException("clinit should not be invoked");
}
}
static Class<?> findClass(Module module, String cn) {
Class<?> c = Class.forName(module, cn);
if (c == null) {
throw new RuntimeException(cn + " not found in " + module);
}
if (c.getModule() != module) {
throw new RuntimeException(c.getModule() + " != " + module);
}
return c;
}
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.lang.reflect.Method;
public class TestMain {
public static void main(String[] args) throws Exception {
ModuleLayer boot = ModuleLayer.boot();
Module m1 = boot.findModule("m1").get();
Module m2 = boot.findModule("m2").get();
// find exported and non-exported class from a named module
findClass(m1, "p1.A");
findClass(m1, "p1.internal.B");
findClass(m2, "p2.C");
// find class from unnamed module
ClassLoader loader = TestMain.class.getClassLoader();
findClass(loader.getUnnamedModule(), "TestDriver");
// check if clinit should not be initialized
// compile without module-path; so use reflection
Class<?> c = Class.forName(m1, "p1.Initializer");
Method m = c.getMethod("isInited");
Boolean isClinited = (Boolean) m.invoke(null);
if (isClinited.booleanValue()) {
throw new RuntimeException("clinit should not be invoked");
}
}
static Class<?> findClass(Module module, String cn) {
Class<?> c = Class.forName(module, cn);
if (c == null) {
throw new RuntimeException(cn + " not found in " + module);
}
if (c.getModule() != module) {
throw new RuntimeException(c.getModule() + " != " + module);
}
return c;
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
module m1 {
exports p1;
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package p1;
public class A {
static {
Initializer.init();
System.out.println("p1.A is initialzed");
}
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package p1;
public class Initializer {
private static boolean inited = false;
static synchronized void init() {
inited = true;
}
public static synchronized boolean isInited() {
return inited;
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package p1.internal;
public class B {
public B() {}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
module m2 {
exports p2;
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package p2;
public class C {
}

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package p2.test;
public class Main {
public static void main(String... args) throws Exception {
ModuleLayer boot = ModuleLayer.boot();
Module m1 = boot.findModule("m1").get();
Module m2 = Main.class.getModule();
// find exported and non-exported class from a named module
findClass(m1, "p1.A");
findClass(m1, "p1.internal.B");
findClass(m2, "p2.C");
// find class from unnamed module
ClassLoader loader = m2.getClassLoader();
findClass(loader.getUnnamedModule(), "TestDriver");
try {
Class<?> c = findClass(m1, "p1.internal.B");
c.newInstance();
throw new RuntimeException(c.getName() + " should not be exported to m2");
} catch (IllegalAccessException e) {}
}
static Class<?> findClass(Module module, String cn) {
Class<?> c = Class.forName(module, cn);
if (c == null) {
throw new RuntimeException(cn + " not found in " + module);
}
if (c.getModule() != module) {
throw new RuntimeException(c.getModule() + " != " + module);
}
return c;
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4028577
@summary Sanity check that Class.getClasses() works.
@author Anand Palaniswamy
*/
public class Sanity {
public class Base {
public class BInner { }
protected class BProtected { }
class BPackage { }
}
public class Derived extends Base {
public class DInner { }
protected class DProtected { }
class DPackage { }
}
public static void main(String[] args) throws Exception {
Class[] c = Derived.class.getClasses();
if (c.length != 2)
throw new Exception("Incorrect number of public classes returned");
for (int i = 0; i < c.length; i++) {
if (c[i] != Base.BInner.class &&
c[i] != Derived.DInner.class)
throw new Exception("Garbage in declared classes");
}
}
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 4028577 4726689
* @summary Sanity check that Class.getDeclaredClasses() works.
*/
public class Sanity {
static class Toplevel { }
class Nested { }
public static void main(String[] args) throws Exception {
class BlockLocal { };
new Object() { };
Class[] c = Sanity.class.getDeclaredClasses();
if (c.length < 2)
throw new Exception("Incorrect number of declared classes");
for (int i = 0; i < c.length; i++) {
String name = c[i].getName();
System.out.println(name);
if (c[i] != Nested.class && c[i] != Toplevel.class
&& !name.matches("\\D\\w*\\$\\d*"))
throw new Exception("Unexpected class: " + name);
}
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 4185857 4726689
* @summary The array returned by getDeclaredClasses doesn't have the
* array element type tag.
*/
public class TypeTag {
private static class Inner { }
public static void main(String[] args) throws Exception {
Class[] v = null;
v = Integer.TYPE.getDeclaredClasses();
if (v == null || v.length != 0)
throw new Exception("Integer.TYPE.getDeclaredClasses is not working");
System.out.println("Integer.TYPE: "+ v.toString());
v = TypeTag.class.getDeclaredClasses();
if (v == null)
throw new Exception("TypeTag.class.getDeclaredClasses returned null");
System.out.println("TypeTag.class: " + v.toString());
int n = 0;
for (int i = 0; i < v.length; i++) {
String name = v[i].getName();
System.out.print(name);
if (!name.matches("\\D\\w*\\$\\d*")) {
n++;
System.out.println(" -- user class");
} else {
System.out.println();
}
}
if (n != 1)
throw new Exception("TypeTag.class.getDeclaredClasses found too many classes");
}
}

View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.lang.reflect.Field;
/**
* @test
* @bug 8065552
* @summary test that all fields returned by getDeclaredFields() can be
* set accessible if package java.lang is open to unnamed module;
* this test also verifies that Class.classLoader final private field
* is hidden from reflection access.
* @modules java.base/java.lang:open
* @run main/othervm ClassDeclaredFieldsTest
*
* @author danielfuchs
*/
public class ClassDeclaredFieldsTest {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws Exception {
System.out.println(System.getProperty("java.version"));
for (Field f : Class.class.getDeclaredFields()) {
f.setAccessible(true);
System.out.println("Field "+f.getName()+" is now accessible.");
if (f.getName().equals("classLoader")) {
throw new RuntimeException("Found "+f.getName()+" field!");
}
}
try {
Class.class.getDeclaredField("classLoader");
throw new RuntimeException("Expected NoSuchFieldException for"
+ " 'classLoader' field not raised");
} catch(NoSuchFieldException x) {
System.out.println("Got expected exception: " + x);
}
System.out.println("Passed");
}
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 4319910
* @summary Verify that exceptions are thrown as expected.
*/
public class Exceptions {
int f0;
public int f1;
private int f2;
protected int f4;
private static final String [] npe = {null};
private static final String [] nsfe = {"f6"};
private static final String [] pass = {"f0", "f1", "f2", "f4"};
private void test(String s, Class ex) {
Throwable t = null;
try {
getClass().getDeclaredField(s);
} catch (Throwable x) {
if (ex.isAssignableFrom(x.getClass()))
t = x;
}
if ((t == null) && (ex != null))
throw new RuntimeException("expected " + ex.getName()
+ " for " + s);
else
System.out.println(s + " OK");
}
public static void main(String [] args) {
Exceptions e = new Exceptions();
for (int i = 0; i < npe.length; i++)
e.test(npe[i], NullPointerException.class);
for (int i = 0; i < nsfe.length; i++)
e.test(nsfe[i], NoSuchFieldException.class);
for (int i = 0; i < pass.length; i++)
e.test(pass[i], null);
}
}

View file

@ -0,0 +1,330 @@
/*
* Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.io.IOException;
import java.io.UncheckedIOException;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.InaccessibleObjectException;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
import jdk.internal.module.Modules;
/**
* @test
* @bug 8065552 8309532
* @summary test that all public fields returned by getDeclaredFields() can
* be set accessible; this test
* loads all classes and get their declared fields
* and call setAccessible(false) followed by setAccessible(true);
* @modules java.base/jdk.internal.module
* @run main/othervm/timeout=480 --add-modules=ALL-SYSTEM FieldSetAccessibleTest
*
* @author danielfuchs
*/
public class FieldSetAccessibleTest {
static final List<String> cantread = new ArrayList<>();
static final List<String> failed = new ArrayList<>();
static final AtomicLong classCount = new AtomicLong();
static final AtomicLong fieldCount = new AtomicLong();
static long startIndex = 0;
static long maxSize = Long.MAX_VALUE;
static long maxIndex = Long.MAX_VALUE;
static final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
// Test that all fields for any given class can be made accessibles
static void testSetFieldsAccessible(Class<?> c) {
Module self = FieldSetAccessibleTest.class.getModule();
Module target = c.getModule();
String pn = c.getPackageName();
boolean exported = self.canRead(target) && target.isExported(pn, self);
for (Field f : c.getDeclaredFields()) {
fieldCount.incrementAndGet();
// setAccessible succeeds only if it's exported and the member
// is public and of a public class, or it's opened
// otherwise it would fail.
boolean isPublic = Modifier.isPublic(f.getModifiers()) &&
Modifier.isPublic(c.getModifiers());
boolean access = (exported && isPublic) || target.isOpen(pn, self);
try {
f.setAccessible(false);
f.setAccessible(true);
if (!access) {
throw new RuntimeException(
String.format("Expected InaccessibleObjectException is not thrown "
+ "for field %s in class %s%n", f.getName(), c.getName()));
}
} catch (InaccessibleObjectException expected) {
if (access) {
throw new RuntimeException(expected);
}
}
}
}
// Performs a series of test on the given class.
// At this time, we only call testSetFieldsAccessible(c)
public static boolean test(Class<?> c, boolean addExports) {
Module self = FieldSetAccessibleTest.class.getModule();
Module target = c.getModule();
String pn = c.getPackageName();
boolean exported = self.canRead(target) && target.isExported(pn, self);
if (addExports && !exported) {
Modules.addExports(target, pn, self);
exported = true;
}
classCount.incrementAndGet();
// Call getDeclaredFields() and try to set their accessible flag.
testSetFieldsAccessible(c);
// add more tests here...
return c == Class.class;
}
// Prints a summary at the end of the test.
static void printSummary(long secs, long millis, long nanos) {
System.out.println("Tested " + fieldCount.get() + " fields of "
+ classCount.get() + " classes in "
+ secs + "s " + millis + "ms " + nanos + "ns");
}
/**
* @param args the command line arguments:
*
* [startIndex (default=0)] [maxSize (default=Long.MAX_VALUE)]
*
* @throws java.lang.Exception if the test fails
*/
public static void main(String[] args) throws Exception {
if (args == null || args.length == 0) {
args = new String[] {"0"};
} else if (args.length > 2) {
throw new RuntimeException("Expected at most one argument. Found "
+ Arrays.asList(args));
}
try {
if (args.length > 0) {
startIndex = Long.parseLong(args[0]);
if (startIndex < 0) {
throw new IllegalArgumentException("startIndex args[0]: "
+ startIndex);
}
}
if (args.length > 1) {
maxSize = Long.parseLong(args[1]);
if (maxSize <= 0) {
maxSize = Long.MAX_VALUE;
}
maxIndex = (Long.MAX_VALUE - startIndex) < maxSize
? Long.MAX_VALUE : startIndex + maxSize;
}
test(listAllClassNames());
} catch (OutOfMemoryError oome) {
System.err.println(classCount.get());
throw oome;
}
}
static Iterable<String> listAllClassNames() {
return new ClassNameJrtStreamBuilder();
}
static void test(Iterable<String> iterable) {
final long start = System.nanoTime();
boolean classFound = false;
int index = 0;
for (String s : iterable) {
if (index == maxIndex) break;
try {
if (index < startIndex) continue;
if (test(s, false)) {
classFound = true;
}
} finally {
index++;
}
}
// Re-test with all packages exported
for (String s : iterable) {
test(s, true);
}
classCount.set(classCount.get() / 2);
fieldCount.set(fieldCount.get() / 2);
long elapsed = System.nanoTime() - start;
long secs = elapsed / 1000_000_000;
long millis = (elapsed % 1000_000_000) / 1000_000;
long nanos = elapsed % 1000_000;
System.out.println("Unreadable path elements: " + cantread);
System.out.println("Failed path elements: " + failed);
printSummary(secs, millis, nanos);
if (!failed.isEmpty()) {
throw new RuntimeException("Test failed for the following classes: " + failed);
}
if (!classFound && startIndex == 0 && index < maxIndex) {
// this is just to verify that we have indeed parsed the java.base module
throw new RuntimeException("Test failed: Class.class not found...");
}
if (classCount.get() == 0 && startIndex == 0) {
throw new RuntimeException("Test failed: no class found?");
}
}
static boolean test(String s, boolean addExports) {
String clsName = s.replace('/', '.').substring(0, s.length() - 6);
try {
System.out.println("Loading " + clsName);
final Class<?> c = Class.forName(
clsName,
false,
systemClassLoader);
return test(c, addExports);
} catch (VerifyError ve) {
System.err.println("VerifyError for " + clsName);
ve.printStackTrace(System.err);
failed.add(s);
} catch (Exception t) {
t.printStackTrace(System.err);
failed.add(s);
} catch (NoClassDefFoundError e) {
e.printStackTrace(System.err);
failed.add(s);
}
return false;
}
static class ClassNameJrtStreamBuilder implements Iterable<String>{
final FileSystem jrt;
final Path root;
final Set<String> modules;
ClassNameJrtStreamBuilder() {
jrt = FileSystems.getFileSystem(URI.create("jrt:/"));
root = jrt.getPath("/modules");
modules = systemModules();
}
@Override
public Iterator<String> iterator() {
try {
return Files.walk(root)
.filter(p -> p.getNameCount() > 2)
.filter(p -> modules.contains(p.getName(1).toString()))
.map(p -> p.subpath(2, p.getNameCount()))
.map(p -> p.toString())
.filter(s -> s.endsWith(".class") && !s.endsWith("module-info.class"))
.iterator();
} catch(IOException x) {
throw new UncheckedIOException("Unable to walk \"/modules\"", x);
}
}
/*
* Filter JVMCI module and its transitive dependences
*/
static Set<String> systemModules() {
// Build module graph and inverse dependences
Set<String> modules = new HashSet<>();
Map<String, Set<String>> moduleToDeps = new HashMap<>();
Map<String, Set<String>> inverseDeps = new HashMap<>();
for (ModuleReference mref : ModuleFinder.ofSystem().findAll()) {
var md = mref.descriptor();
modules.add(md.name());
Set<String> deps = md.requires().stream().map(ModuleDescriptor.Requires::name)
.collect(Collectors.toSet());
moduleToDeps.put(md.name(), deps);
inverseDeps.put(md.name(), new HashSet<>());
}
// reverse edges
moduleToDeps.keySet().forEach(u -> {
moduleToDeps.get(u)
.forEach(v -> inverseDeps.get(v)
.add(u));
});
Set<String> mods = Set.of(
// All JVMCI packages other than jdk.vm.ci.services are dynamically
// exported to Graal
"jdk.graal.compiler", "jdk.graal.compiler.management"
);
// Filters all modules that directly or indirectly require Graal modules
// as these are upgradeable and also provide APIs to add qualified exports dynamically
Set<String> filters = mods.stream().flatMap(mn -> findDeps(mn, inverseDeps).stream())
.collect(Collectors.toSet());
System.out.println("Filtered modules: " + filters);
return modules.stream()
.filter(mn -> !filters.contains(mn))
.collect(Collectors.toSet());
}
/*
* Traverse the graph to find all the dependences from the given name.
*/
static Set<String> findDeps(String name, Map<String, Set<String>> graph) {
Set<String> visited = new HashSet<>();
Deque<String> deque = new LinkedList<>();
deque.add(name);
String node;
while (!deque.isEmpty()) {
node = deque.pop();
if (visited.contains(node))
continue;
visited.add(node);
Set<String> deps = graph.get(node);
if (deps != null)
deque.addAll(deps);
}
return visited;
}
}
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 4319910
* @summary Verify that exceptions are thrown as expected.
*/
public class Exceptions {
void m0() {}
public void m1() {}
private void m2() {}
protected void m4() {}
private static final String [] npe = {null};
private static final String [] nsme = {"m6"};
private static final String [] pass = {"m0", "m1", "m2", "m4"};
private void test(String s, Class ex) {
Throwable t = null;
try {
getClass().getDeclaredMethod(s, new Class[] {});
} catch (Throwable x) {
if (ex.isAssignableFrom(x.getClass()))
t = x;
}
if ((t == null) && (ex != null))
throw new RuntimeException("expected " + ex.getName()
+ " for " + s);
else
System.out.println(s + " OK");
}
public static void main(String [] args) {
Exceptions e = new Exceptions();
for (int i = 0; i < npe.length; i++)
e.test(npe[i], NullPointerException.class);
for (int i = 0; i < nsme.length; i++)
e.test(nsme[i], NoSuchMethodException.class);
for (int i = 0; i < pass.length; i++)
e.test(pass[i], null);
}
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4028577
@summary Sanity check that Class.getDeclaringClass() works.
@author Anand Palaniswamy
*/
public class Sanity {
class Nested {
}
public static void main(String[] args) throws Exception {
if (Nested.class.getDeclaringClass() != Sanity.class)
throw new Exception("Not finding declaring class");
/* This will pass on old VM's that return null when this
* method was unimplemented. But write the test to keep
* regression from happening in the current code.
*/
class BlockLocal {
};
if (BlockLocal.class.getDeclaringClass() != null)
throw new Exception("Finding declaring class for block local");
}
}

View file

@ -0,0 +1,363 @@
/*
* Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
*
* @summary Check getEnclosingClass and other methods
* @author Peter von der Ahé
*
* a) Top level classes
* b) Nested classes (static member classes)
* c) Inner classes (non-static member classes)
* d) Local classes (named classes declared within a method)
* e) Anonymous classes
*/
/*
* TODO:
* Test annotations
* Test Locals in static initializers
* Test Locals in methods
* Test Locals in constructors
* Test interfaces
* Test enums
* Test method with a String[] argument
*/
//package
import common.TestMe;
interface MakeClass {
Class<?> make();
}
public class EnclosingClass {
public EnclosingClass() {
aec = (new Object() {}).getClass();
}
static class Nested {
static class NestedNested {
}
class NestedInner {
}
Class<?> nestedLocal0;
Class<?> nestedLocal1;
Class<?> nestedLocal2;
{
class NestedLocal0 {};
nestedLocal0 = NestedLocal0.class;
nestedMethod1();
nestedMethod2(null);
}
void nestedMethod1() {
class NestedLocal1 {}
nestedLocal1 = NestedLocal1.class;
}
void nestedMethod2(String[] args) {
class NestedLocal2 {}
nestedLocal2 = NestedLocal2.class;
}
Class<?> nestedAnonymous = (new Object() {}).getClass();
static enum NestedNestedEnum {
}
enum NestedInnerEnum {
}
}
class Inner {
class InnerInner {
}
Class<?> innerLocal0;
Class<?> innerLocal1;
Class<?> innerLocal2;
{
class InnerLocal0 {
};
innerLocal0 = InnerLocal0.class;
innerMethod1();
innerMethod2(null);
}
void innerMethod1() {
class InnerLocal1 {}
innerLocal1 = InnerLocal1.class;
}
void innerMethod2(String[] args) {
class InnerLocal2 {}
innerLocal2 = InnerLocal2.class;
}
Class<?> innerAnonymous = (new Object() {}).getClass();
}
@TestMe(desc="top level class",
encl="null",
simple="EnclosingClass",
canonical="EnclosingClass")
public Class<?> a = EnclosingClass.class;
@TestMe(desc="nested class within top level class",
encl="class EnclosingClass",
simple="Nested",
canonical="EnclosingClass.Nested")
public Class<?> ab = Nested.class;
@TestMe(desc="inner class within top level class",
encl="class EnclosingClass",
simple="Inner",
canonical="EnclosingClass.Inner")
public Class<?> ac = Inner.class;
@TestMe(desc="local class within top level class",
encl="class EnclosingClass",
simple="Local0",
hasCanonical=false)
public Class<?> ad0;
@TestMe(desc="local class within top level class",
encl="class EnclosingClass",
simple="Local1",
hasCanonical=false)
public Class<?> ad1;
@TestMe(desc="local class within top level class",
encl="class EnclosingClass",
simple="Local2",
hasCanonical=false)
public Class<?> ad2;
@TestMe(desc="local class within a top level class static initializer" ,
encl="class EnclosingClass",
simple="StaticLocal0",
hasCanonical=false)
public Class<?> sad0;
@TestMe(desc="local class within a top level class static method" ,
encl="class EnclosingClass",
simple="StaticLocal1",
hasCanonical=false)
public Class<?> sad1;
@TestMe(desc="local class within a top level class static method",
encl="class EnclosingClass",
simple="StaticLocal2",
hasCanonical=false)
public Class<?> sad2;
{
class Local0 {
class LocalInner {}
{
class LocalLocal {};
dd = LocalLocal.class;
de = (new Object() {}).getClass();
}
};
ad0 = Local0.class;
dc = Local0.LocalInner.class;
new Local0();
method1();
method2(null);
sad0 = staticLocal0;
sad1 = staticMethod1();
sad2 = staticMethod2(null);
}
static Class<?> staticLocal0;
static {
class StaticLocal0 {};
staticLocal0 = StaticLocal0.class;
}
static Class<?> staticMethod1() {
class StaticLocal1 {};
return StaticLocal1.class;
}
static Class<?> staticMethod2(String[] args) {
class StaticLocal2 {};
return StaticLocal2.class;
}
void method1() {
class Local1 {};
ad1 = Local1.class;
}
void method2(String[] args) {
class Local2 {};
ad2 = Local2.class;
}
@TestMe(desc="anonymous class within top level class",
encl="class EnclosingClass",
simple="",
hasCanonical=false)
public Class<?> ae = (new Object() {}).getClass();
@TestMe(desc="anonymous class within top level class constructor",
encl="class EnclosingClass",
simple="",
hasCanonical=false)
public Class<?> aec;
@TestMe(desc="nested class within nested class",
encl="class EnclosingClass$Nested",
simple="NestedNested",
canonical="EnclosingClass.Nested.NestedNested")
public Class<?> bb = Nested.NestedNested.class;
@TestMe(desc="inner class within nested class",
encl="class EnclosingClass$Nested",
simple="NestedInner",
canonical="EnclosingClass.Nested.NestedInner")
public Class<?> bc = Nested.NestedInner.class;
@TestMe(desc="local class within nested class",
encl="class EnclosingClass$Nested",
simple="NestedLocal0",
hasCanonical=false)
public Class<?> bd0 = (new Nested()).nestedLocal0;
@TestMe(desc="local class within nested class",
encl="class EnclosingClass$Nested",
simple="NestedLocal1",
hasCanonical=false)
public Class<?> bd1 = (new Nested()).nestedLocal1;
@TestMe(desc="local class within nested class",
encl="class EnclosingClass$Nested",
simple="NestedLocal2",
hasCanonical=false)
public Class<?> bd2 = (new Nested()).nestedLocal2;
@TestMe(desc="anonymous class within nested class",
encl="class EnclosingClass$Nested",
simple="",
hasCanonical=false)
public Class<?> be = (new Nested()).nestedAnonymous;
@TestMe(desc="nested class within an inner class", encl="", simple="")
public Class<?> cb = Void.class; // not legal
@TestMe(desc="inner class within an inner class",
encl="class EnclosingClass$Inner",
simple="InnerInner",
canonical="EnclosingClass.Inner.InnerInner")
public Class<?> cc = ((new Inner()).new InnerInner()).getClass();
@TestMe(desc="local class within an inner class",
encl="class EnclosingClass$Inner",
simple="InnerLocal0",
hasCanonical=false)
public Class<?> cd = (new Inner()).innerLocal0;
@TestMe(desc="anonymous class within an inner class",
encl="class EnclosingClass$Inner",
simple="",
hasCanonical=false)
public Class<?> ce = (new Inner()).innerAnonymous;
@TestMe(desc="nested class within a local class", encl="", simple="")
public Class<?> db = Void.class; // not legal
@TestMe(desc="inner class within a local class",
encl="class EnclosingClass$1Local0",
simple="LocalInner",
hasCanonical=false)
public Class<?> dc; // initialized above
@TestMe(desc="local class within a local class",
encl="class EnclosingClass$1Local0",
simple="LocalLocal",
hasCanonical=false)
public Class<?> dd; // initialized above
@TestMe(desc="anonymous class within a local class",
encl="class EnclosingClass$1Local0",
simple="",
hasCanonical=false)
public Class<?> de; // initialized above
@TestMe(desc="nested class within an anonymous class", encl="", simple="")
public Class<?> eb = Void.class; // not legal
@TestMe(desc="inner class within an anonymous class",
encl="class EnclosingClass$3",
simple="AnonymousInner",
hasCanonical=false)
public Class<?> ec = new MakeClass() {
class AnonymousInner {}
public Class<?> make() { return AnonymousInner.class; }
}.make();
@TestMe(desc="local class within an anonymous class",
encl="class EnclosingClass$4",
simple="AnonymousLocal",
hasCanonical=false)
public Class<?> ed = new MakeClass() {
Class<?> c;
{
class AnonymousLocal {}
c = AnonymousLocal.class;
}
public Class<?> make() { return c; }
}.make();
@TestMe(desc="anonymous class within an anonymous class",
encl="class EnclosingClass$5",
simple="",
hasCanonical=false)
public Class<?> ee = new MakeClass() {
Class<?> c;
{
c = new Object() {}.getClass();
}
public Class<?> make() { return c; }
}.make();
@TestMe(desc="the primitive boolean type",
encl="null",
simple="boolean",
canonical="boolean")
public Class<?> booleanClass = boolean.class;
@TestMe(desc="the primitive char type",
encl="null",
simple="char",
canonical="char")
public Class<?> charClass = char.class;
@TestMe(desc="the primitive byte type",
encl="null",
simple="byte",
canonical="byte")
public Class<?> byteClass = byte.class;
@TestMe(desc="the primitive short type",
encl="null",
simple="short",
canonical="short")
public Class<?> shortClass = short.class;
@TestMe(desc="the primitive int type",
encl="null",
simple="int",
canonical="int")
public Class<?> intClass = int.class;
@TestMe(desc="the primitive long type",
encl="null",
simple="long",
canonical="long")
public Class<?> longClass = long.class;
@TestMe(desc="the primitive float type",
encl="null",
simple="float",
canonical="float")
public Class<?> floatClass = float.class;
@TestMe(desc="the primitive double type",
encl="null",
simple="double",
canonical="double")
public Class<?> doubleClass = double.class;
@TestMe(desc="the primitive void type",
encl="null",
simple="void",
canonical="void")
public Class<?> voidClass = void.class;
}

View file

@ -0,0 +1,208 @@
/*
* Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4992173 4992170
* @library /test/lib
* @modules jdk.compiler
* @run testng/othervm EnclosingClassTest
* @summary Check getEnclosingClass and other methods
* @author Peter von der Ahé
*/
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Path;
import common.TestMe;
import jdk.test.lib.compiler.CompilerUtils;
import jdk.test.lib.util.FileUtils;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/*
* We have five kinds of classes:
* a) Top level classes
* b) Nested classes (static member classes)
* c) Inner classes (non-static member classes)
* d) Local classes (named classes declared within a method)
* e) Anonymous classes
*
* Each one can be within a package or not.
* Kinds b-e can/must be within kinds a-e.
* This gives us a three dimensional space:
* 1. dimension: b-e
* 2. dimension: a-e
* 3. dimension: packages
*
* We make a two dimensional matrix of (b-e)x(a-e) and change the
* package configuration on that:
*
* b c d e
* a x x x x
* b x x x x
* c o x x x where o means "not legal"
* d o x x x
* e o x x x
*/
public class EnclosingClassTest {
private static final String SRC_DIR = System.getProperty("test.src");
private static final Path ENCLOSING_CLASS_SRC = Path.of(SRC_DIR, "EnclosingClass.java");
private static final String GEN_SRC_DIR = "gensrc";
@BeforeClass
public void createEnclosingClasses() throws IOException {
Path pkg1Dir = Path.of(GEN_SRC_DIR, "pkg1");
Path pkg2Dir = Path.of(GEN_SRC_DIR, "pkg1", "pkg2");
Path pkg1File = pkg1Dir.resolve("EnclosingClass.java");
Path pkg2File = pkg2Dir.resolve("EnclosingClass.java");
if (!Files.notExists(pkg1Dir)) {
FileUtils.deleteFileTreeWithRetry(pkg1Dir);
}
Files.createDirectories(pkg2Dir);
createAndWriteEnclosingClasses(ENCLOSING_CLASS_SRC, pkg1File, "pkg1");
createAndWriteEnclosingClasses(ENCLOSING_CLASS_SRC, pkg2File, "pkg1.pkg2");
Assert.assertTrue(CompilerUtils.compile(ENCLOSING_CLASS_SRC, Path.of(System.getProperty("test.classes")),
"--source-path", SRC_DIR));
Assert.assertTrue(CompilerUtils.compile(pkg1File, Path.of(System.getProperty("test.classes")),
"-classpath", System.getProperty("test.class.path")));
Assert.assertTrue(CompilerUtils.compile(pkg2File, Path.of(System.getProperty("test.classes")),
"-classpath", System.getProperty("test.class.path")));
}
@Test
public void testEnclosingClasses() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
InvocationTargetException, InstantiationException {
test(Class.forName("EnclosingClass").getDeclaredConstructor().newInstance());
}
@Test
public void testEnclosingClassesInPackage() throws ClassNotFoundException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException, InstantiationException {
test(Class.forName("pkg1.EnclosingClass").getDeclaredConstructor().newInstance());
}
@Test
public void testEnclosingClassesInNestedPackage() throws ClassNotFoundException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException, InstantiationException {
test(Class.forName("pkg1.pkg2.EnclosingClass").getDeclaredConstructor().newInstance());
}
private void createAndWriteEnclosingClasses(Path source, Path target, String packageName) throws IOException {
String className = packageName + ".EnclosingClass";
try (BufferedReader br = new BufferedReader(new FileReader(source.toFile()));
PrintWriter bw = new PrintWriter(new FileWriter(target.toFile()))) {
String line;
while ((line = br.readLine()) != null) {
if (line.contains("canonical=\"EnclosingClass")) {
line = line.replaceAll("canonical=\"EnclosingClass", "canonical=\"" + className);
} else if (line.contains("\"class EnclosingClass")) {
line = line.replaceAll("\"class EnclosingClass", "\"class " + className);
} else if (line.contains("//package")) {
line = line.replaceAll("//package", "package " + packageName + ";");
}
bw.println(line);
}
}
}
private void info(Class<?> c, Class<?> encClass, String desc) {
if (!"".equals(desc)) {
System.out.println(desc + ":");
}
System.out.println(c);
System.out.println("\tis enclosed by:\t\t" + encClass);
System.out.println("\thas simple name:\t`" +
c.getSimpleName() + "'");
System.out.println("\thas canonical name:\t`" +
c.getCanonicalName() + "'");
}
private void match(String actual, String expected) {
Assert.assertTrue((actual == null && expected == null) || actual.equals(expected));
System.out.println("\t`" +
actual + "' matches expected `" +
expected + "'");
}
private void check(Class<?> c, Class<?> enc,
String encName, String encNameExpected,
String simpleName, String simpleNameExpected,
String canonicalName, String canonicalNameExpected) {
match(encName, encNameExpected);
match(simpleName, simpleNameExpected);
match(canonicalName, canonicalNameExpected);
}
private void testClass(Class<?> c, TestMe annotation, Field f) {
if (Void.class.equals(c))
return;
Class<?> encClass = c.getEnclosingClass();
c.getEnclosingMethod(); // make sure it does not crash
c.getEnclosingConstructor(); // make sure it does not crash
info(c, encClass, annotation.desc());
check(c, encClass,
""+encClass, annotation.encl(),
c.getSimpleName(), annotation.simple(),
c.getCanonicalName(),
annotation.hasCanonical() ? annotation.canonical() : null);
if (void.class.equals(c))
return;
Class<?> array = java.lang.reflect.Array.newInstance(c, 0).getClass();
check(array, array.getEnclosingClass(),
"", "",
array.getSimpleName(), annotation.simple()+"[]",
array.getCanonicalName(),
annotation.hasCanonical() ? annotation.canonical()+"[]" : null);
}
private void test(Object tests) {
for (Field f : tests.getClass().getFields()) {
TestMe annotation = f.getAnnotation(TestMe.class);
if (annotation != null) {
try {
testClass((Class<?>)f.get(tests), annotation, f);
} catch (AssertionError ex) {
System.err.println("Error in " +
tests.getClass().getName() +
"." + f.getName());
throw ex;
} catch (IllegalAccessException ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
}
}
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4992170
*
* @run main/othervm -esa -ea T4992170
*
* @summary enclosing type parameter missing in anonymous and local classes
* @author Neal Gafter
*/
import java.lang.reflect.*;
class A<T> {
Object o = new Object() {
public T t;
};
}
public class T4992170 {
public static void main(String[] args) throws NoSuchFieldException {
Type t = new A<Integer>().o.getClass().getField("t").getGenericType();
if (!(t instanceof TypeVariable))
throw new Error("" + t);
}
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @summary Check getEnclosingClass and other methods
* @author Peter von der Ahé
*/
package common;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface TestMe {
String desc();
String encl();
String simple();
boolean hasCanonical() default true;
String canonical() default "";
}

View file

@ -0,0 +1,101 @@
/*
* Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4962341 6832557
* @summary Check getEnclosingMethod method
*/
import java.lang.reflect.Constructor;
import java.lang.annotation.*;
public class EnclosingConstructorTests {
static Class<?> anonymousClass;
static Class<?> localClass;
static Class<?> anotherLocalClass;
static {
Cloneable c = new Cloneable() {}; // anonymous cloneable
anonymousClass = c.getClass();
}
@ConstructorDescriptor("EnclosingConstructorTests()")
EnclosingConstructorTests() {
class Local {};
Local l = new Local();
localClass = l.getClass();
}
@ConstructorDescriptor("private EnclosingConstructorTests(int)")
private EnclosingConstructorTests(int i) {
class Local {};
Local l = new Local();
anotherLocalClass = l.getClass();
}
static int examine(Class<?> enclosedClass, String constructorSig) {
Constructor<?> c = enclosedClass.getEnclosingConstructor();
if (c == null && constructorSig == null)
return 0;
if (c != null &&
c.getAnnotation(ConstructorDescriptor.class).value().equals(constructorSig))
return 0; // everything is okay
else {
System.err.println("\nUnexpected constructor value; expected:\t" + constructorSig +
"\ngot:\t" + c);
return 1;
}
}
public static void main(String argv[]) {
int failures = 0;
class StaticLocal {};
EnclosingConstructorTests ect = new EnclosingConstructorTests();
ect = new EnclosingConstructorTests(5);
failures += examine(StaticLocal.class,
null);
failures += examine(localClass,
"EnclosingConstructorTests()");
failures += examine(anotherLocalClass,
"private EnclosingConstructorTests(int)");
failures += examine(anonymousClass,
null);
if (failures > 0)
throw new RuntimeException("Test failed.");
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface ConstructorDescriptor {
String value();
}

View file

@ -0,0 +1,132 @@
/*
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8350704
* @summary Test behaviors with various bad EnclosingMethod attribute
* @library /test/lib
* @run junit BadEnclosingMethodTest
*/
import jdk.test.lib.ByteCodeLoader;
import org.junit.jupiter.api.Test;
import java.lang.classfile.ClassFile;
import java.lang.classfile.attribute.EnclosingMethodAttribute;
import java.lang.reflect.GenericSignatureFormatError;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import java.util.Optional;
import static java.lang.constant.ConstantDescs.INIT_NAME;
import static org.junit.jupiter.api.Assertions.*;
class BadEnclosingMethodTest {
private static Path classPath(String className) {
return Path.of(System.getProperty("test.classes"), className + ".class");
}
/**
* Loads a test class that is transformed from the Enclosed local class in
* the Encloser::work method. This local class has its EnclosingMethod
* attribute transformed to the specific name and type, which may be malformed
* strings.
*
* @param name the new enclosing method name, may be malformed
* @param type the new enclosing method type, may be malformed
* @return the loaded test class, for reflective inspection
*/
private Class<?> loadTestClass(String name, String type) throws Exception {
var outerName = "Encloser";
var className = outerName + "$1Enclosed";
var cf = ClassFile.of();
var cm = cf.parse(classPath(className));
var bytes = cf.transformClass(cm, (cb, ce) -> {
if (ce instanceof EnclosingMethodAttribute em) {
var cp = cb.constantPool();
var enclosingMethodName = cp.utf8Entry(name);
var enclosingMethodType = cp.utf8Entry(type); // a malformed method type
cb.with(EnclosingMethodAttribute.of(em.enclosingClass(), Optional.of(cp.nameAndTypeEntry(
enclosingMethodName, enclosingMethodType
))));
} else {
cb.with(ce);
}
});
var map = Map.of(
outerName, Files.readAllBytes(classPath(outerName)),
className, bytes
);
return new ByteCodeLoader(map, BadEnclosingMethodTest.class.getClassLoader())
.loadClass(className);
}
/**
* Test reflection behaviors when the EnclosingMethod attribute's type is
* an invalid string.
*/
@Test
void testMalformedTypes() throws Exception {
assertThrowsExactly(ClassFormatError.class, () -> loadTestClass("methodName", "(L[;)V"));
assertThrowsExactly(ClassFormatError.class, () -> loadTestClass(INIT_NAME, "(L[;)V"));
assertThrowsExactly(ClassFormatError.class, () -> loadTestClass(INIT_NAME, "(Lmissing/;)V"));
assertThrowsExactly(ClassFormatError.class, () -> loadTestClass(INIT_NAME, "()L/Missing;"));
// only throw if the query type match the method/constructor type
assertDoesNotThrow(() -> loadTestClass(INIT_NAME, "Ljava/lang/Object;").getEnclosingMethod());
assertDoesNotThrow(() -> loadTestClass("method", "[I").getEnclosingConstructor());
// We have to manually intercept field-typed "methods"
assertThrows(GenericSignatureFormatError.class, () -> loadTestClass(INIT_NAME, "Ljava/lang/Object;").getEnclosingConstructor());
assertThrows(GenericSignatureFormatError.class, () -> loadTestClass("method", "[I").getEnclosingMethod());
}
/**
* Test reflective behaviors when the EnclosingMethod attribute's type is
* valid, but refers to a class or interface that cannot be found.
*/
@Test
void testAbsentMethods() throws Exception {
var absentMethodType = loadTestClass("methodName", "(Ldoes/not/Exist;)V");
var ex = assertThrows(TypeNotPresentException.class,
absentMethodType::getEnclosingMethod);
assertEquals("does.not.Exist", ex.typeName());
var absentConstructorType = loadTestClass(INIT_NAME, "(Ldoes/not/Exist;)V");
ex = assertThrows(TypeNotPresentException.class,
absentConstructorType::getEnclosingConstructor);
assertEquals("does.not.Exist", ex.typeName());
}
}
class Encloser {
private static void work() {
class Enclosed {
}
}
}

View file

@ -0,0 +1,88 @@
/*
* Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4962341
* @summary Check getEnclosingMethod method
*/
import java.lang.reflect.Method;
import java.lang.annotation.*;
public class EnclosingMethodTests {
static Class<?> anonymousClass;
static {
Cloneable c = new Cloneable() {}; // anonymous cloneable
anonymousClass = c.getClass();
}
EnclosingMethodTests() {}
@MethodDescriptor("java.lang.Class EnclosingMethodTests.getLocalClass(Object o)")
Class getLocalClass(Object o) {
class Local {};
Local l = new Local();
return l.getClass();
}
static int examine(Class enclosedClass, String methodSig) {
Method m = enclosedClass.getEnclosingMethod();
if (m == null && methodSig == null)
return 0;
if (m != null &&
m.getAnnotation(MethodDescriptor.class).value().equals(methodSig))
return 0; // everything is okay
else {
System.err.println("\nUnexpected method value; expected:\t" + methodSig +
"\ngot:\t" + m);
return 1;
}
}
@MethodDescriptor("public static void EnclosingMethodTests.main(java.lang.String[])")
public static void main(String argv[]) {
int failures = 0;
class StaticLocal {};
failures += examine(StaticLocal.class,
"public static void EnclosingMethodTests.main(java.lang.String[])");
failures += examine( (new EnclosingMethodTests()).getLocalClass(null),
"java.lang.Class EnclosingMethodTests.getLocalClass(Object o)");
failures += examine(EnclosingMethodTests.class, null);
failures += examine(anonymousClass, null);
if (failures > 0)
throw new RuntimeException("Test failed.");
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface MethodDescriptor {
String value();
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
super final enum class BadEnum1 extends java/lang/Enum
version 52:0
{
public Method values:"()[LBadEnum1;"
stack 1
{
iconst_0;
anewarray BadEnum1;
areturn;
}
}

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
super final enum class BadEnum2
extends java/lang/Enum
version 52:0
{
public static Method values:"()Ljava/lang/Object;"
stack 2
{
new class java/lang/Object;
dup;
invokespecial Method java/lang/Object."<init>":"()V";
areturn;
}
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8296196
* @summary Test getEnumConstants on bad Enums
* @build BadEnum1 BadEnum2
* @run junit BadEnumTest
*/
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class BadEnumTest {
@Test
void testBadEnum1() {
assertNull(BadEnum1.class.getEnumConstants(), "Expected BadEnum1.class.getEnumConstants() to return null");
}
@Test
void testBadEnum2() {
assertNull(BadEnum2.class.getEnumConstants(), "Expected BadEnum2.class.getEnumConstants() to return null");
}
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 5047859
* @summary verify that for an array type class instance, getField("length")
* throws an exception, and getFields() does not contain a Field for
* 'length'
*/
import java.lang.reflect.Field;
public class ArrayLength {
public static void main(String [] args) {
int failed = 0;
try {
new String[0].getClass().getField("length");
failed++;
System.out.println("getField(\"length\") should throw NoSuchFieldException");
} catch (NoSuchFieldException e) {
}
try {
new String[0].getClass().getDeclaredField("length");
failed++;
System.out.println("getDeclaredField(\"length\") should throw NoSuchFieldException");
} catch (NoSuchFieldException e) {
}
if (new String[0].getClass().getFields().length != 0) {
failed++;
System.out.println("getFields() for an array type should return a zero length array");
}
if (new String[0].getClass().getDeclaredFields().length != 0) {
failed++;
System.out.println("getDeclaredFields() for an array type should return a zero length array");
}
if (failed != 0)
throw new RuntimeException("Test failed see log for details");
}
}

View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 4319910
* @summary Verify that exceptions are thrown as expected.
*/
public class Exceptions {
private static boolean ok = true;
int f0;
public int f1;
private int f2;
protected int f4;
private static final String [] npe = {null};
private static final String [] nsfe = {"f0", "f2", "f4", "f6"};
private static final String [] pass = {"f1"};
private void test(String s, Class ex) {
Throwable t = null;
try {
getClass().getField(s);
} catch (Throwable x) {
if (ex.isAssignableFrom(x.getClass()))
t = x;
}
if ((t == null) && (ex != null)) {
ok = false;
System.out.println("expected " + ex.getName() + " for " + s
+ " -- FAILED");
} else {
System.out.println(s + " -- OK");
}
}
public static void main(String [] args) {
Exceptions e = new Exceptions();
for (int i = 0; i < npe.length; i++)
e.test(npe[i], NullPointerException.class);
for (int i = 0; i < nsfe.length; i++)
e.test(nsfe[i], NoSuchFieldException.class);
for (int i = 0; i < pass.length; i++)
e.test(pass[i], null);
if (!ok)
throw new RuntimeException("some tests failed");
}
}

View file

@ -0,0 +1,168 @@
/*
* Copyright 2014 Google, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 8063147
* @summary Tests for Class.getFields().
* @run testng Sanity
*/
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
public class Sanity {
public interface EmptyInterface {}
class EmptyClass {}
interface BI1 {
public int i = 1;
int j = 2;
}
interface BI2 {
int k = 1;
}
public interface DI extends BI1, BI2, EmptyInterface {
int m = 5;
}
interface DDI extends DI {
int n = 6;
}
public class D extends EmptyClass {
public int publicDField;
protected int protectedDField;
private int privateDField;
}
class DD extends D {
public int publicDDField;
protected int protectedDDField;
private int privateDDField;
}
public class Universe extends DD implements DDI {
public int publicUniverseField;
protected int protectedUniverseField;
private int privateUniverseField;
}
void assertContainsNoFields(Class<?> clazz) {
assertEquals(clazz.getFields().length, 0);
}
@Test
public void primitiveTypesHaveNoFields() throws Exception {
assertContainsNoFields(byte.class);
assertContainsNoFields(char.class);
assertContainsNoFields(short.class);
assertContainsNoFields(int.class);
assertContainsNoFields(long.class);
assertContainsNoFields(boolean.class);
assertContainsNoFields(void.class);
assertContainsNoFields(double.class);
assertContainsNoFields(float.class);
}
@Test
public void arrayTypesHaveNoFields() throws Exception {
assertContainsNoFields(byte[].class);
assertContainsNoFields(Object[].class);
assertContainsNoFields(java.util.Map[].class);
assertContainsNoFields(java.util.HashMap[].class);
}
@Test
public void emptyInterfacesHaveNoFields() throws Exception {
assertContainsNoFields(EmptyInterface.class);
}
@Test
public void emptyClassesHaveNoFields() throws Exception {
assertContainsNoFields(EmptyClass.class);
class EmptyLocalClass {}
assertContainsNoFields(EmptyLocalClass.class);
}
void assertContainsFields(Class<?> clazz, int count) {
assertEquals(clazz.getFields().length, count);
}
@Test
public void checkFieldCounts() throws Exception {
assertContainsFields(BI1.class, 2);
assertContainsFields(BI2.class, 1);
assertContainsFields(DI.class, 4);
assertContainsFields(DDI.class, 5);
assertContainsFields(D.class, 1);
assertContainsFields(DD.class, 2);
assertContainsFields(Universe.class, 8);
}
void assertContainsFields(Class<?> derived, Class<?> base) {
List<Field> derivedFields = Arrays.asList(derived.getFields());
List<Field> baseFields = Arrays.asList(base.getFields());
assertTrue(derivedFields.containsAll(baseFields));
}
List<Class<?>> directSupers(Class<?> clazz) {
List<Class<?>> directSupers = new ArrayList<>();
directSupers.addAll(Arrays.asList(clazz.getInterfaces()));
if (clazz.getSuperclass() != null) {
directSupers.add(clazz.getSuperclass());
}
return directSupers;
}
void assertContainsSuperFields(Class<?> clazz) {
for (Class<?> directSuper : directSupers(clazz)) {
assertContainsFields(clazz, directSuper);
}
}
List<Class<?>> testClasses() {
List<Class<?>> testClasses = new ArrayList<>();
testClasses.add(Sanity.class);
testClasses.addAll(Arrays.asList(Sanity.class.getDeclaredClasses()));
assertEquals(testClasses.size(), 10);
return testClasses;
}
@Test
public void fieldsAreInheritedFromSupers() throws Exception {
for (Class clazz : testClasses()) {
assertContainsSuperFields(clazz);
}
}
@Test
public void getFieldIsConsistentWithGetFields() throws Exception {
for (Class clazz : testClasses()) {
for (Field field : clazz.getFields()) {
assertEquals(field, clazz.getField(field.getName()));
}
}
}
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 4319910
* @summary Verify that exceptions are thrown as expected.
*/
public class Exceptions {
void m0() {}
public void m1() {}
private void m2() {}
protected void m4() {}
private static final String [] npe = {null};
private static final String [] nsme = {"m0", "m2", "m4", "m6"};
private static final String [] pass = {"m1"};
private void test(String s, Class ex) {
Throwable t = null;
try {
getClass().getMethod(s, new Class[] {});
} catch (Throwable x) {
if (ex.isAssignableFrom(x.getClass()))
t = x;
}
if ((t == null) && (ex != null))
throw new RuntimeException("expected " + ex.getName()
+ " for " + s);
else
System.out.println(s + " OK");
}
public static void main(String [] args) {
Exceptions e = new Exceptions();
for (int i = 0; i < npe.length; i++)
e.test(npe[i], NullPointerException.class);
for (int i = 0; i < nsme.length; i++)
e.test(nsme[i], NoSuchMethodException.class);
for (int i = 0; i < pass.length; i++)
e.test(pass[i], null);
}
}

View file

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

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4187388
@summary <clinit> in interfaces need not be public
*/
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
interface TestedInterface {
String s = System.getProperty("Test");
void foo();
void bar();
}
public class NonPublicStaticInitializer {
public static void main(String args[]) throws Exception {
Method m[] = TestedInterface.class.getMethods();
for (int i = 0; i < m.length; i++) {
System.out.println("Found: " +
Modifier.toString(m[i].getModifiers()) +
" " + m[i].getName());
if (m[i].getName().equals("<clinit>")) {
throw new Exception("Shouldn't have found <clinit>");
}
}
}
}

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 4654698
* @summary Verify that expected methods are returned for star inheritance.
*/
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.ArrayList;
// D.m
interface A1 extends B1, C1 {}
interface B1 extends D1 {}
interface C1 extends D1 {}
interface D1 { void m(); }
// A.m
interface A2 extends B2, C2 { void m(); }
interface B2 extends D2 {}
interface C2 extends D2 {}
interface D2 { void m(); }
// B.m, C.m
interface A3 extends B3, C3 {}
interface B3 extends D3 { void m(); }
interface C3 extends D3 { void m(); }
interface D3 { void m() ; }
// B.m
interface A4 extends B4, C4 {}
interface B4 extends D4 { void m(); }
interface C4 extends D4 {}
interface D4 { void m(); }
public class StarInheritance {
private static int n = 1;
private static void test(Method [] ma, ArrayList expect) {
System.out.println("Test " + n++);
if (expect.size() != ma.length) {
System.err.println(" found methods: " + Arrays.asList(ma));
System.err.println(" expected locations: " + expect);
throw new RuntimeException("found = " + ma.length
+"; expected = " + expect.size());
}
for (int i = 0; i < ma.length; i++) {
Method m = ma[i];
System.out.println(" " + m.toString());
int n;
if (m.getName().equals("m")
&& (n = expect.indexOf(m.getDeclaringClass())) != -1) {
expect.remove(n);
} else {
throw new RuntimeException("unable to locate method in class: "
+ m.getDeclaringClass());
}
}
}
public static void main(String [] args) {
Class [] l1 = {D1.class};
test(A1.class.getMethods(), new ArrayList(Arrays.asList(l1)));
Class [] l2 = {A2.class};
test(A2.class.getMethods(), new ArrayList(Arrays.asList(l2)));
Class [] l3 = {B3.class, C3.class};
test(A3.class.getMethods(), new ArrayList(Arrays.asList(l3)));
Class [] l4 = {B4.class};
test(A4.class.getMethods(), new ArrayList(Arrays.asList(l4)));
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4109635
@summary For an inner class, the access bits must come from the
InnerClasses attribute, not from the class block's access.
Note however that the VM should not rely on these access
flags from the attribute!
*/
import java.lang.reflect.Modifier;
public class ForInnerClass {
private class Inner {
}
protected class Protected {
}
public static void main(String[] args) throws Exception {
/* We are not testing for the ACC_SUPER bug, so strip we strip
* synchorized. */
int m = 0;
m = Inner.class.getModifiers() & (~Modifier.SYNCHRONIZED);
if (m != Modifier.PRIVATE)
throw new Exception("Access bits for innerclass not from " +
"InnerClasses attribute");
m = Protected.class.getModifiers() & (~Modifier.SYNCHRONIZED);
if (m != Modifier.PROTECTED)
throw new Exception("Protected inner class wronged modifiers");
}
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4163105
@summary VM loses static modifier of inner class.
*/
import java.lang.reflect.Modifier;
public class ForStaticInnerClass {
static class Static {
}
public static void main(String[] args) throws Exception {
if (!Modifier.isStatic(Static.class.getModifiers()))
throw new Exception("VM lost static modifier of innerclass.");
}
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4127549
@summary getModifiers should resolve constant pool entries from
its own class.
@author James Bond
*/
import java.lang.reflect.Modifier;
public class ResolveFrom {
private class Inner {
int i;
}
public static void main(String argv[]) throws Exception {
int m = ResolveFrom.class.getModifiers();
System.out.println("ResolveFrom has modifiers = " +
Modifier.toString(m));
}
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
@bug 4109635
@summary VM adds ACC_SUPER bit to access flags of a class. This must
be stripped by the Class.getModifiers method, or else this
shows up as though the class is synchronized and that doesn't
make any sense.
@author Anand Palaniswamy
*/
public class StripACC_SUPER {
public static void main(String[] args) throws Exception {
int access = StripACC_SUPER.class.getModifiers();
if (java.lang.reflect.Modifier.isSynchronized(access))
throw new Exception("ACC_SUPER bit is not being stripped");
}
}

View file

@ -0,0 +1,136 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.lang.reflect.Modifier;
import java.lang.annotation.*;
/*
* @test
* @bug 8296743
* @summary Verify array classes and primitives have expected modifiers
*/
@ExpectedModifiers(Modifier.PUBLIC | Modifier.FINAL | Modifier.ABSTRACT)
public class TestPrimitiveAndArrayModifiers {
/*
* Relevant excerpt of the Class.getModifiers() specification:
* <p> If the underlying class is an array class:
* <ul>
* <li> its {@code public}, {@code private} and {@code protected}
* modifiers are the same as those of its component type
* <li> its {@code final} and {@code abstract} modifiers are always
* {@code true}
* <li> its interface modifier is always {@code false}, even when
* the component type is an interface
* </ul>
*/
public static void main(String... args) throws Exception {
testPrimitives();
testArrays();
}
private static void testArrays() {
Class<?>[] testCases = {
TestPrimitiveAndArrayModifiers.class,
PackagePrivateClass.class,
ProtectedClass.class,
PrivateClass.class,
PublicInterface.class,
PackagePrivateInterface.class,
ProtectedInterface.class,
PrivateInterface.class,
};
for(var testCase : testCases) {
int expectedModifiers =
testCase.getAnnotation(ExpectedModifiers.class).value();
Class<?> arrayClass = testCase.arrayType();
int actualModifiers = arrayClass.getModifiers();
if (expectedModifiers != actualModifiers) {
throw new RuntimeException("Expected " + Modifier.toString(expectedModifiers) +
"on " + testCase.getCanonicalName() +
", but got " + Modifier.toString(actualModifiers));
}
}
}
@ExpectedModifiers(Modifier.FINAL | Modifier.ABSTRACT)
class PackagePrivateClass {}
@ExpectedModifiers(Modifier.FINAL | Modifier.ABSTRACT | Modifier.PROTECTED)
protected class ProtectedClass {}
@ExpectedModifiers(Modifier.FINAL | Modifier.ABSTRACT | Modifier.PRIVATE)
private class PrivateClass {}
@ExpectedModifiers(Modifier.FINAL | Modifier.ABSTRACT | Modifier.PUBLIC)
public interface PublicInterface {}
@ExpectedModifiers(Modifier.FINAL | Modifier.ABSTRACT)
interface PackagePrivateInterface {}
@ExpectedModifiers(Modifier.FINAL | Modifier.ABSTRACT | Modifier.PROTECTED)
protected interface ProtectedInterface {}
@ExpectedModifiers(Modifier.FINAL | Modifier.ABSTRACT | Modifier.PRIVATE)
private interface PrivateInterface {}
/*
* Relevant excerpt of the Class.getModifiers() specification:
*
* If this {@code Class} object represents a primitive type or
* void, its {@code public}, {@code abstract}, and {@code final}
* modifiers are always {@code true}.
*/
private static void testPrimitives() {
Class<?>[] testCases = {
void.class,
boolean.class,
byte.class,
short.class,
char.class,
int.class,
float.class,
long.class,
double.class,
};
for(var testCase : testCases) {
int actualModifiers = testCase.getModifiers();
if ((Modifier.PUBLIC | Modifier.ABSTRACT | Modifier.FINAL) !=
actualModifiers) {
throw new RuntimeException("Bad modifiers " +
Modifier.toString(actualModifiers) +
" on primitive type " + testCase);
}
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface ExpectedModifiers {
int value() default 0;
}

View file

@ -0,0 +1,194 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @compile Basic.java
* @run testng p.Basic
* @summary Basic test for java.lang.Class::getPackageName
*/
package p;
import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;
import static org.testng.Assert.*;
public class Basic {
// -- member classes --
static class Nested {
static class Foo { }
}
Class<?> getNestedClass1() {
return Nested.class;
}
Class<?> getNestedClass2() {
return Nested.Foo.class;
}
class Inner {
class Foo { }
}
Class<?> getInnerClass1() {
return Inner.class;
}
Class<?> getInnerClass2() {
return Inner.Foo.class;
}
// -- local and anonymous classes --
Class<?> getLocalClass1() {
class Local { }
return Local.class;
}
Class<?> getLocalClass2() {
class Local {
class Foo { }
}
return Local.Foo.class;
}
Class<?> getLocalClass3() {
class Local {
final Class<?> c;
Local() {
class Foo { }
this.c = Foo.class;
}
Class<?> get() {
return c;
}
}
return new Local().get();
}
Class<?> getAnonymousClass1() {
Runnable r = new Runnable() { public void run() { } };
return r.getClass();
}
Class<?> getAnonymousClass2() {
class Local {
Class<?> get() {
Runnable r = new Runnable() { public void run() { } };
return r.getClass();
}
}
return new Local().get();
}
Class<?> getAnonymousClass3() {
Runnable r = () -> { };
return r.getClass();
}
Class<?> getAnonymousClass4() {
class Local {
Class<?> get() {
Runnable r = () -> { };
return r.getClass();
}
}
return new Local().get();
}
Class<?> getAnonymousClass5() {
class Local {
final Class<?> c;
Local() {
Runnable r = new Runnable() { public void run() { } };
this.c = r.getClass();
}
Class<?> get() {
return c;
}
}
return new Local().get();
}
Class<?> getAnonymousClass6() {
class Local {
final Class<?> c;
Local() {
Runnable r = () -> { };
this.c = r.getClass();
}
Class<?> get() {
return c;
}
}
return new Local().get();
}
static final String TEST_PACKAGE = Basic.class.getPackage().getName();
@DataProvider(name = "classes")
public Object[][] classes() {
return new Object[][] {
{ Basic.class, TEST_PACKAGE },
{ Basic[].class, TEST_PACKAGE },
{ Basic[][].class, TEST_PACKAGE },
{ getNestedClass1(), TEST_PACKAGE },
{ getNestedClass2(), TEST_PACKAGE },
{ getInnerClass1(), TEST_PACKAGE },
{ getInnerClass2(), TEST_PACKAGE },
{ getLocalClass1(), TEST_PACKAGE },
{ getLocalClass2(), TEST_PACKAGE },
{ getLocalClass3(), TEST_PACKAGE },
{ getAnonymousClass1(), TEST_PACKAGE },
{ getAnonymousClass2(), TEST_PACKAGE },
{ getAnonymousClass3(), TEST_PACKAGE },
{ getAnonymousClass4(), TEST_PACKAGE },
{ getAnonymousClass5(), TEST_PACKAGE },
{ getAnonymousClass6(), TEST_PACKAGE },
{ Object.class, "java.lang" },
{ Object[].class, "java.lang" },
{ Object[][].class, "java.lang" },
{ int.class, "java.lang" },
{ int[].class, "java.lang" },
{ int[][].class, "java.lang" },
{ void.class, "java.lang" },
};
}
@Test(dataProvider = "classes")
public void testPackageName(Class<?> type, String expected) {
assertEquals(type.getPackageName(), expected);
}
}

View file

@ -0,0 +1,300 @@
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.lang.module.Configuration;
import java.lang.module.ResolvedModule;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Basic test of Class getResource and getResourceAsStream to locate/read
* resources in named modules.
*/
public class Main {
static final String NAME = "myresource";
public static void main(String[] args) throws IOException {
// create resources in m1
createResource("m1", Paths.get("."), "m1");
createResource("m1", Paths.get("p1"), "m1/p1");
createResource("m1", Paths.get("p1", "impl"), "m1/p1.impl");
createResource("m1", Paths.get("p1", "resources"), "m1/p1.resources");
// create resources in m2
createResource("m2", Paths.get("."), "m2");
createResource("m2", Paths.get("p2"), "m2/p2");
createResource("m2", Paths.get("p2", "impl"), "m2/p2.impl");
createResource("m2", Paths.get("p2", "resources"), "m2/p2.resources");
// invoke Class getResource from an unnamed module.
URL url = Main.class.getResource("/" + NAME);
assertNotNull(url);
url = Main.class.getResource("/p1/" + NAME);
assertNull(url);
url = Main.class.getResource("/p1/impl/" + NAME);
assertNull(url);
url = Main.class.getResource("/p1/resources/" + NAME);
assertEquals(readAllAsString(url), "m1/p1.resources");
url = Main.class.getResource("/p2/" + NAME);
assertNull(url);
url = Main.class.getResource("/p2/impl/" + NAME);
assertNull(url);
// m1: exports private p1.resources
url = Main.class.getResource("/p2/resources/" + NAME);
assertNull(url);
// invoke Class getResource from module m1
url = p1.Main.getResource("/" + NAME);
assertEquals(readAllAsString(url), "m1");
url = p1.Main.getResource("/p1/" + NAME);
assertEquals(readAllAsString(url), "m1/p1");
url = p1.Main.getResource("/p1/impl/" + NAME);
assertEquals(readAllAsString(url), "m1/p1.impl");
url = p1.Main.getResource("/p1/resources/" + NAME);
assertEquals(readAllAsString(url), "m1/p1.resources");
// m2: not a named package
url = p1.Main.getResource(p2.Main.class, "/" + NAME);
assertEquals(readAllAsString(url), "m2");
url = p1.Main.getResource(p2.Main.class, "/p2/" + NAME);
assertNull(url);
// m2: exports p2.impl to m1
url = p1.Main.getResource(p2.Main.class, "/p2/impl/" + NAME);
assertNull(url);
// m2: exports private p2.resources to m1;
url = p1.Main.getResource(p2.Main.class, "/p2/resources/" + NAME);
assertEquals(readAllAsString(url), "m2/p2.resources");
// invoke Class getResource from module m2
url = p2.Main.getResource("/" + NAME);
assertEquals(readAllAsString(url), "m2");
url = p2.Main.getResource("/p2/" + NAME);
assertEquals(readAllAsString(url), "m2/p2");
url = p2.Main.getResource("/p2/impl/" + NAME);
assertEquals(readAllAsString(url), "m2/p2.impl");
url = p2.Main.getResource("/p2/resources/" + NAME);
assertEquals(readAllAsString(url), "m2/p2.resources");
// m1: not a named package
url = p2.Main.getResource(p1.Main.class, "/" + NAME);
assertEquals(readAllAsString(url), "m1");
url = p2.Main.getResource(p1.Main.class, "/p1/" + NAME);
assertNull(url);
url = p2.Main.getResource(p1.Main.class, "/p1/impl/" + NAME);
assertNull(url);
// m1: exports private p1.resources;
url = p2.Main.getResource(p1.Main.class, "/p1/resources/" + NAME);
assertEquals(readAllAsString(url), "m1/p1.resources");
// invoke Class getResourceAsStream from an unnamed module.
InputStream in = Main.class.getResourceAsStream("/" + NAME);
assertNotNull(in);
in = Main.class.getResourceAsStream("/p1/" + NAME);
assertNull(in);
in = Main.class.getResourceAsStream("/p1/impl/" + NAME);
assertNull(in);
in = Main.class.getResourceAsStream("/p1/resources/" + NAME);
assertEquals(readAllAsString(in), "m1/p1.resources");
in = Main.class.getResourceAsStream("/p2/" + NAME);
assertNull(in);
in = Main.class.getResourceAsStream("/p2/impl/" + NAME);
assertNull(in);
in = Main.class.getResourceAsStream("/p2/resources/" + NAME);
assertNull(in);
// invoke Class getResourceAsStream from module m1
in = p1.Main.getResourceAsStream("/" + NAME);
assertEquals(readAllAsString(in), "m1");
in = p1.Main.getResourceAsStream("/p1/" + NAME);
assertEquals(readAllAsString(in), "m1/p1");
in = p1.Main.getResourceAsStream("/p1/impl/" + NAME);
assertEquals(readAllAsString(in), "m1/p1.impl");
in = p1.Main.getResourceAsStream("/p1/resources/" + NAME);
assertEquals(readAllAsString(in), "m1/p1.resources");
in = p1.Main.getResourceAsStream(p2.Main.class, "/" + NAME);
assertEquals(readAllAsString(in), "m2");
in = p1.Main.getResourceAsStream(p2.Main.class, "/p2/" + NAME);
assertNull(in);
in = p1.Main.getResourceAsStream(p2.Main.class, "/p2/impl/" + NAME);
assertNull(in);
in = p1.Main.getResourceAsStream(p2.Main.class, "/p2/resources/" + NAME);
assertEquals(readAllAsString(in), "m2/p2.resources");
// invoke Class getResourceAsStream from module m2
in = p2.Main.getResourceAsStream("/" + NAME);
assertEquals(readAllAsString(in), "m2");
in = p2.Main.getResourceAsStream("/p2/" + NAME);
assertEquals(readAllAsString(in), "m2/p2");
in = p2.Main.getResourceAsStream("/p2/impl/" + NAME);
assertEquals(readAllAsString(in), "m2/p2.impl");
in = p2.Main.getResourceAsStream("/p2/resources/" + NAME);
assertEquals(readAllAsString(in), "m2/p2.resources");
in = p2.Main.getResourceAsStream(p1.Main.class, "/" + NAME);
assertEquals(readAllAsString(in), "m1");
in = p2.Main.getResourceAsStream(p1.Main.class, "/p1/" + NAME);
assertNull(in);
in = p2.Main.getResourceAsStream(p1.Main.class, "/p1/impl/" + NAME);
assertNull(in);
in = p2.Main.getResourceAsStream(p1.Main.class, "/p1/resources/" + NAME);
assertEquals(readAllAsString(in), "m1/p1.resources");
// Nulls
try {
Main.class.getResource(null);
assertTrue(false);
} catch (NullPointerException expected) { }
try {
Main.class.getResourceAsStream(null);
assertTrue(false);
} catch (NullPointerException expected) { }
try {
p1.Main.class.getResource(null);
assertTrue(false);
} catch (NullPointerException expected) { }
try {
p1.Main.class.getResourceAsStream(null);
assertTrue(false);
} catch (NullPointerException expected) { }
System.out.println("Success!");
}
/**
* Create a resource in the sub-directory of the given exploded module
*/
static void createResource(String mn, Path subdir, String msg) throws IOException {
Path dir = directoryFor(mn).resolve(subdir);
Path file = dir.resolve(NAME);
Files.write(file, msg.getBytes("UTF-8"));
}
/**
* Returns the directory for the given module (by name).
*/
static Path directoryFor(String name) {
Configuration cf = ModuleLayer.boot().configuration();
ResolvedModule resolvedModule = cf.findModule(name).orElse(null);
if (resolvedModule == null)
throw new RuntimeException("not found: " + name);
Path dir = Paths.get(resolvedModule.reference().location().get());
if (!Files.isDirectory(dir))
throw new RuntimeException("not a directory: " + dir);
return dir;
}
static String readAllAsString(InputStream in) throws IOException {
if (in == null)
return null;
try (in) {
return new String(in.readAllBytes(), "UTF-8");
}
}
static String readAllAsString(URL url) throws IOException {
if (url == null)
return null;
InputStream in = url.openStream();
return readAllAsString(url.openStream());
}
static void assertTrue(boolean condition) {
if (!condition) throw new RuntimeException();
}
static void assertNull(Object o) {
assertTrue(o == null);
}
static void assertNotNull(Object o) {
assertTrue(o != null);
}
static void assertEquals(Object actual, Object expected) {
if (expected == null) {
assertNull(actual);
} else {
assertTrue(expected.equals(actual));
}
}
static void assertNotEquals(Object actual, Object expected) {
if (expected == null) {
assertNotNull(actual);
} else {
assertTrue(!expected.equals(actual));
}
}
}

View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.nio.file.Path;
import java.nio.file.Paths;
import static jdk.test.lib.process.ProcessTools.executeTestJava;
import jdk.test.lib.compiler.CompilerUtils;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
/**
* @test
* @library /test/lib
* @modules jdk.compiler
* @build ResourcesTest jdk.test.lib.compiler.CompilerUtils
* @run testng ResourcesTest
* @summary Driver for basic test of Class getResource and getResourceAsStream
*/
@Test
public class ResourcesTest {
private static final String TEST_SRC = System.getProperty("test.src");
private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
private static final Path CLASSES_DIR = Paths.get("classes");
private static final Path MODS_DIR = Paths.get("mods");
/**
* Compiles the modules used by the test and the test Main
*/
@BeforeTest
public void compileAll() throws Exception {
boolean compiled;
// javac -modulesource mods -d mods src/**
compiled = CompilerUtils
.compile(SRC_DIR,
MODS_DIR,
"--module-source-path", SRC_DIR.toString());
assertTrue(compiled);
// javac --module-path mods -d classes Main.java
compiled = CompilerUtils
.compile(Paths.get(TEST_SRC, "Main.java"),
CLASSES_DIR,
"--module-path", MODS_DIR.toString(),
"--add-modules", "m1,m2");
assertTrue(compiled);
}
/**
* Run the test
*/
public void runTest() throws Exception {
int exitValue
= executeTestJava("--module-path", MODS_DIR.toString(),
"--add-modules", "m1,m2",
"-cp", CLASSES_DIR.toString(),
"Main")
.outputTo(System.out)
.errorTo(System.out)
.getExitValue();
assertTrue(exitValue == 0);
}
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
module m1 {
exports p1;
opens p1.resources;
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package p1;
import java.io.InputStream;
import java.net.URL;
public class Main {
private Main() { }
public static URL getResource(String name) {
return Main.class.getResource(name);
}
public static InputStream getResourceAsStream(String name) {
return Main.class.getResourceAsStream(name);
}
public static URL getResource(Class<?> c, String name) {
return c.getResource(name);
}
public static InputStream getResourceAsStream(Class<?> c, String name) {
return c.getResourceAsStream(name);
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package p1.impl;
public class Type { }

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package p1.resources;
public class Type { }

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
module m2 {
exports p2;
exports p2.impl to m1;
opens p2.resources to m1;
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package p2;
import java.io.InputStream;
import java.net.URL;
public class Main {
private Main() { }
public static URL getResource(String name) {
return Main.class.getResource(name);
}
public static InputStream getResourceAsStream(String name) {
return Main.class.getResourceAsStream(name);
}
public static URL getResource(Class<?> c, String name) {
return c.getResource(name);
}
public static InputStream getResourceAsStream(Class<?> c, String name) {
return c.getResourceAsStream(name);
}
}

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package p2.impl;
public class Type { }

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package p2.resources;
public class Type { }

View file

@ -0,0 +1,222 @@
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @bug 8057919
* @summary Class.getSimpleName() should work for non-JLS compliant class names
*/
import java.lang.classfile.ClassBuilder;
import java.lang.classfile.ClassFile;
import java.lang.classfile.CodeBuilder;
import java.lang.classfile.attribute.EnclosingMethodAttribute;
import java.lang.classfile.attribute.InnerClassInfo;
import java.lang.classfile.attribute.InnerClassesAttribute;
import java.lang.constant.ClassDesc;
import java.lang.reflect.AccessFlag;
import java.util.Optional;
import static java.lang.classfile.ClassFile.ACC_PUBLIC;
import static java.lang.classfile.ClassFile.ACC_STATIC;
import static java.lang.constant.ConstantDescs.CD_Object;
import static java.lang.constant.ConstantDescs.INIT_NAME;
import static java.lang.constant.ConstantDescs.MTD_void;
public class GetSimpleNameTest {
static class NestedClass {}
class InnerClass {}
static Class<?> f1() {
class LocalClass {}
return LocalClass.class;
}
public static void main(String[] args) throws Exception {
assertEquals(NestedClass.class.getSimpleName(), "NestedClass");
assertEquals( InnerClass.class.getSimpleName(), "InnerClass");
assertEquals( f1().getSimpleName(), "LocalClass");
java.io.Serializable anon = new java.io.Serializable() {};
assertEquals(anon.getClass().getSimpleName(), "");
// Java class names, prepended enclosing class name.
testNested("p.Outer$Nested", "p.Outer", "Nested");
testInner( "p.Outer$Inner", "p.Inner", "Inner");
testLocal( "p.Outer$1Local", "p.Outer", "Local");
testAnon( "p.Outer$1", "p.Outer", "");
// Non-Java class names, prepended enclosing class name.
testNested("p.$C1$Nested", "p.$C1$", "Nested");
testInner( "p.$C1$Inner", "p.$C1$", "Inner");
testLocal( "p.$C1$Local", "p.$C1$", "Local");
testAnon( "p.$C1$1", "p.$C1$", "");
// Non-Java class names, unrelated class names.
testNested("p1.$Nested$", "p2.$C1$", "Nested");
testInner( "p1.$Inner$", "p2.$C1$", "Inner");
testLocal( "p1.$Local$", "p2.$C1$", "Local");
testAnon( "p1.$anon$", "p2.$C1$", "");
}
static void testNested(String innerName, String outerName, String simpleName) throws Exception {
BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName);
CustomCL cl = new CustomCL(innerName, outerName, bg.getNestedClasses(true), bg.getNestedClasses(false));
assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName);
}
static void testInner(String innerName, String outerName, String simpleName) throws Exception {
BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName);
CustomCL cl = new CustomCL(innerName, outerName, bg.getInnerClasses(true), bg.getInnerClasses(false));
assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName);
}
static void testLocal(String innerName, String outerName, String simpleName) throws Exception {
BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName);
CustomCL cl = new CustomCL(innerName, outerName, bg.getLocalClasses(true), bg.getLocalClasses(false));
assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName);
}
static void testAnon(String innerName, String outerName, String simpleName) throws Exception {
BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName);
CustomCL cl = new CustomCL(innerName, outerName, bg.getAnonymousClasses(true), bg.getAnonymousClasses(false));
assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName);
}
static void assertEquals(Object o1, Object o2) {
if (!java.util.Objects.equals(o1, o2)) {
throw new AssertionError(o1 + " != " + o2);
}
}
static class CustomCL extends ClassLoader {
final String innerName;
final String outerName;
final byte[] innerClassFile;
final byte[] outerClassFile;
CustomCL(String innerName, String outerName, byte[] innerClassFile, byte[] outerClassFile) {
this.innerName = innerName;
this.outerName = outerName;
this.innerClassFile = innerClassFile;
this.outerClassFile = outerClassFile;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
if (innerName.equals(name)) {
return defineClass(innerName, innerClassFile, 0, innerClassFile.length);
} else if (outerName.equals(name)) {
return defineClass(outerName, outerClassFile, 0, outerClassFile.length);
} else {
throw new ClassNotFoundException(name);
}
}
}
static class BytecodeGenerator {
final ClassDesc innerName;
final ClassDesc outerName;
final String simpleName;
BytecodeGenerator(String innerName, String outerName, String simpleName) {
this.innerName = ClassDesc.of(innerName);
this.outerName = ClassDesc.of(outerName);
this.simpleName = simpleName;
}
static void makeDefaultCtor(ClassBuilder clb) {
clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cb -> {
cb.aload(0);
cb.invokespecial(CD_Object, INIT_NAME, MTD_void);
cb.return_();
});
}
void makeCtxk(ClassBuilder clb, boolean isInner) {
if (isInner) {
clb.with(EnclosingMethodAttribute.of(outerName,
Optional.of("f"), Optional.of(MTD_void)));
} else {
clb.withMethodBody("f", MTD_void, ACC_PUBLIC | ACC_STATIC,
CodeBuilder::return_);
}
}
byte[] getNestedClasses(boolean isInner) {
var name = (isInner ? innerName : outerName);
return ClassFile.of().build(name, clb -> {
clb.withSuperclass(CD_Object);
clb.withFlags(AccessFlag.PUBLIC, AccessFlag.SUPER);
clb.with(InnerClassesAttribute.of(
InnerClassInfo.of(innerName,
Optional.of(outerName),
Optional.of(simpleName))));
makeDefaultCtor(clb);
});
}
byte[] getInnerClasses(boolean isInner) {
var name = (isInner ? innerName : outerName);
return ClassFile.of().build(name, clb -> {
clb.withSuperclass(CD_Object);
clb.withFlags(AccessFlag.PUBLIC, AccessFlag.SUPER);
clb.with(InnerClassesAttribute.of(
InnerClassInfo.of(innerName,
Optional.of(outerName),
Optional.of(simpleName),
AccessFlag.PUBLIC)));
makeDefaultCtor(clb);
});
}
byte[] getLocalClasses(boolean isInner) {
var name = (isInner ? innerName : outerName);
return ClassFile.of().build(name, clb -> {
clb.withSuperclass(CD_Object);
clb.withFlags(AccessFlag.PUBLIC, AccessFlag.SUPER);
clb.with(InnerClassesAttribute.of(
InnerClassInfo.of(innerName,
Optional.empty(),
Optional.of(simpleName),
AccessFlag.PUBLIC, AccessFlag.STATIC)));
makeDefaultCtor(clb);
makeCtxk(clb, isInner);
});
}
byte[] getAnonymousClasses(boolean isInner) {
var name = (isInner ? innerName : outerName);
return ClassFile.of().build(name, clb -> {
clb.withSuperclass(CD_Object);
clb.withFlags(AccessFlag.PUBLIC, AccessFlag.SUPER);
clb.with(InnerClassesAttribute.of(
InnerClassInfo.of(innerName,
Optional.empty(),
Optional.empty(),
AccessFlag.PUBLIC, AccessFlag.STATIC)));
makeDefaultCtor(clb);
makeCtxk(clb, isInner);
});
}
}
}