# HG changeset patch # User ccheung # Date 1565911421 25200 # Node ID a89ec7fc99aacf5e39d5d62f6ccae1991d9e24d4 # Parent 2c66dbb9422722a95549dfc087864b7d4374d9fb 8226645: [TESTBUG] some AppCDS tests rely on illegal reflective access Summary: Updated tests to use Lookup.defineClass instead of ClassLoader.defineClass. Reviewed-by: iklam, dholmes, alanb diff -r 2c66dbb94227 -r a89ec7fc99aa test/hotspot/jtreg/runtime/cds/appcds/RewriteBytecodesTest.java --- a/test/hotspot/jtreg/runtime/cds/appcds/RewriteBytecodesTest.java Thu Aug 15 19:29:58 2019 +0000 +++ b/test/hotspot/jtreg/runtime/cds/appcds/RewriteBytecodesTest.java Thu Aug 15 16:23:41 2019 -0700 @@ -24,7 +24,7 @@ /* * @test - * @summary Use ClassLoader.defineClass() to load a class with rewritten bytecode. Make sure + * @summary Use Lookup.defineClass() to load a class with rewritten bytecode. Make sure * the archived class with the same name is not loaded. * @requires vm.cds * @library /test/lib @@ -52,7 +52,6 @@ OutputAnalyzer output = TestCommon.exec(appJar, // command-line arguments ... - "--add-opens=java.base/java.lang=ALL-UNNAMED", use_whitebox_jar, "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", diff -r 2c66dbb94227 -r a89ec7fc99aa test/hotspot/jtreg/runtime/cds/appcds/customLoader/LoaderSegregationTest.java --- a/test/hotspot/jtreg/runtime/cds/appcds/customLoader/LoaderSegregationTest.java Thu Aug 15 19:29:58 2019 +0000 +++ b/test/hotspot/jtreg/runtime/cds/appcds/customLoader/LoaderSegregationTest.java Thu Aug 15 16:23:41 2019 -0700 @@ -63,7 +63,7 @@ String wbJar = JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox"); String use_whitebox_jar = "-Xbootclasspath/a:" + wbJar; - String appJar = JarBuilder.build("LoaderSegregation_app", "LoaderSegregation", + String appJar = JarBuilder.build("LoaderSegregation_app", "LoaderSegregation", "LoaderSegregation$1", "CustomLoadee", "CustomLoadee2", "CustomLoadee3Child", "CustomInterface2_ia", "OnlyBuiltin", "Util"); @@ -110,8 +110,6 @@ output = TestCommon.exec(TestCommon.concatPaths(appJar, app2Jar), // command-line arguments ... - "--add-opens=java.base/java.lang=ALL-UNNAMED", - "--add-opens=java.base/java.security=ALL-UNNAMED", use_whitebox_jar, "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", diff -r 2c66dbb94227 -r a89ec7fc99aa test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/LoaderSegregation.java --- a/test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/LoaderSegregation.java Thu Aug 15 19:29:58 2019 +0000 +++ b/test/hotspot/jtreg/runtime/cds/appcds/customLoader/test-classes/LoaderSegregation.java Thu Aug 15 16:23:41 2019 -0700 @@ -81,8 +81,25 @@ } { // UNREGISTERED LOADER - URLClassLoader urlClassLoader = new URLClassLoader(urls); - Class c2 = Util.defineClassFromJAR(urlClassLoader, jarFile, ONLY_BUILTIN); + URLClassLoader urlClassLoader = new URLClassLoader(urls) { + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + synchronized (getClassLoadingLock(name)) { + Class c = findLoadedClass(name); + if (c == null) { + try { + c = findClass(name); + } catch (ClassNotFoundException e) { + c = getParent().loadClass(name); + } + } + if (resolve) { + resolveClass(c); + } + return c; + } + } + }; + Class c2 = urlClassLoader.loadClass(ONLY_BUILTIN); if (c2.getClassLoader() != urlClassLoader) { throw new RuntimeException("Error in test"); diff -r 2c66dbb94227 -r a89ec7fc99aa test/hotspot/jtreg/runtime/cds/appcds/test-classes/RewriteBytecodes.java --- a/test/hotspot/jtreg/runtime/cds/appcds/test-classes/RewriteBytecodes.java Thu Aug 15 19:29:58 2019 +0000 +++ b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/RewriteBytecodes.java Thu Aug 15 16:23:41 2019 -0700 @@ -23,6 +23,7 @@ */ import java.io.File; +import java.lang.invoke.MethodHandles; import sun.hotspot.WhiteBox; public class RewriteBytecodes { @@ -30,7 +31,7 @@ String from = "___xxx___"; String to = "___yyy___"; File clsFile = new File(args[0]); - Class superClass = Util.defineModifiedClass(RewriteBytecodes.class.getClassLoader(), clsFile, from, to); + Class superClass = Util.defineModifiedClass(MethodHandles.lookup(), clsFile, from, to); Child child = new Child(); diff -r 2c66dbb94227 -r a89ec7fc99aa test/hotspot/jtreg/runtime/cds/appcds/test-classes/Util.java --- a/test/hotspot/jtreg/runtime/cds/appcds/test-classes/Util.java Thu Aug 15 19:29:58 2019 +0000 +++ b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/Util.java Thu Aug 15 16:23:41 2019 -0700 @@ -23,19 +23,21 @@ */ import java.io.*; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.*; import java.util.jar.*; public class Util { /** - * Invoke the loader.defineClass() class method to define the class stored in clsFile, + * Define the class as stored in clsFile with the provided lookup instance, * with the following modification: * */ - public static Class defineModifiedClass(ClassLoader loader, File clsFile, String fromString, String toString) + public static Class defineModifiedClass(Lookup lookup, File clsFile, String fromString, String toString) throws FileNotFoundException, IOException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { @@ -46,14 +48,11 @@ System.out.println("Loading from: " + clsFile + " (" + buff.length + " bytes)"); - Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", - buff.getClass(), int.class, int.class); - defineClass.setAccessible(true); - // We directly call into ClassLoader.defineClass() to define the "Super" class. Also, + // We directly call into Lookup.defineClass() to define the "Super" class. Also, // rewrite its classfile so that it returns ___yyy___ instead of ___xxx___. Changing the // classfile will guarantee that this class will NOT be loaded from the CDS archive. - Class cls = (Class)defineClass.invoke(loader, buff, new Integer(0), new Integer(buff.length)); + Class cls = lookup.defineClass(buff); System.out.println("Loaded : " + cls); return cls; @@ -105,44 +104,6 @@ return b; } - public static Class defineClassFromJAR(ClassLoader loader, File jarFile, String className) - throws FileNotFoundException, IOException, NoSuchMethodException, IllegalAccessException, - InvocationTargetException { - return defineClassFromJAR(loader, jarFile, className, null, null); - } - - /** - * Invoke the loader.defineClass() class method to define the named class stored in a JAR file. - * - * If a class exists both in the classpath, as well as in the list of URLs of a URLClassLoader, - * by default, the URLClassLoader will not define the class, and instead will delegate to the - * app loader. This method is an easy way to force the class to be defined by the URLClassLoader. - * - * Optionally, you can modify the contents of the classfile buffer. See comments in - * defineModifiedClass. - */ - public static Class defineClassFromJAR(ClassLoader loader, File jarFile, String className, - String fromString, String toString) - throws FileNotFoundException, IOException, NoSuchMethodException, IllegalAccessException, - InvocationTargetException - { - byte[] buff = getClassFileFromJar(jarFile, className); - - if (fromString != null) { - replace(buff, fromString, toString); - } - - //System.out.println("Loading from: " + ent + " (" + buff.length + " bytes)"); - - Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", - buff.getClass(), int.class, int.class); - defineClass.setAccessible(true); - Class cls = (Class)defineClass.invoke(loader, buff, new Integer(0), new Integer(buff.length)); - - //System.out.println("Loaded : " + cls); - return cls; - } - public static byte[] getClassFileFromJar(File jarFile, String className) throws FileNotFoundException, IOException { JarFile jf = new JarFile(jarFile); JarEntry ent = jf.getJarEntry(className.replace('.', '/') + ".class");