Path: blob/master/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/ModifyAnonymous.java
41153 views
/*1* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @library /test/lib26* @summary Test that retransforming and redefining anonymous classes gets UnmodifiableClassException27* @requires vm.jvmti28* @modules java.base/jdk.internal.misc29* @modules java.instrument30* jdk.jartool/sun.tools.jar31* @run main ModifyAnonymous buildagent32* @run main/othervm -javaagent:redefineagent.jar ModifyAnonymous33*/3435import java.io.File;36import java.io.FileNotFoundException;37import java.io.FileOutputStream;38import java.io.PrintWriter;39import java.lang.RuntimeException;40import java.lang.instrument.ClassDefinition;41import java.lang.instrument.ClassFileTransformer;42import java.lang.instrument.IllegalClassFormatException;43import java.lang.instrument.Instrumentation;44import java.security.ProtectionDomain;4546import jdk.test.lib.compiler.InMemoryJavaCompiler;47import jdk.test.lib.helpers.ClassFileInstaller;4849public class ModifyAnonymous {5051public static class LambdaTransformer implements ClassFileTransformer {52@Override53public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,54ProtectionDomain protectionDomain, byte[] classfileBuffer)55throws IllegalClassFormatException {56return null;57}58}5960static Instrumentation inst = null;61static volatile boolean done = false;6263public static void premain(String args, Instrumentation instrumentation) {6465inst = instrumentation;66System.out.println("javaagent in da house!");67instrumentation.addTransformer(new LambdaTransformer());68}6970private static void buildAgent() {71try {72ClassFileInstaller.main("ModifyAnonymous");73} catch (Exception e) {74throw new RuntimeException("Could not write agent classfile", e);75}7677try {78PrintWriter pw = new PrintWriter("MANIFEST.MF");79pw.println("Premain-Class: ModifyAnonymous");80pw.println("Agent-Class: ModifyAnonymous");81pw.println("Can-Retransform-Classes: true");82pw.println("Can-Redefine-Classes: true");83pw.close();84} catch (FileNotFoundException e) {85throw new RuntimeException("Could not write manifest file for the agent", e);86}8788sun.tools.jar.Main jarTool = new sun.tools.jar.Main(System.out, System.err, "jar");89if (!jarTool.run(new String[] { "-cmf", "MANIFEST.MF", "redefineagent.jar", "ModifyAnonymous.class" })) {90throw new RuntimeException("Could not write the agent jar file");91}92}9394public static class InstanceMethodCallSiteApp {9596public static void test() throws InterruptedException {97for (int i = 0; i < 2; i++) {98InstanceMethodCallSiteApp app = new InstanceMethodCallSiteApp();99Runnable r = app::doWork; // this creates an anonymous class100while (!done) {101r.run();102Thread.sleep(10);103}104}105}106107public void doWork() {108System.out.print(".");109}110}111112static void runTest() {113PrintWriter pw;114String logName = System.getProperty("test.classes") +115File.separator + "loadedClasses.log";116// Create a log file to capture the names of the classes in the117// allLoadedClasses array. The log file is for assisting in debugging118// in case a null class is encountered in the allLoadedClasses array.119try {120pw = new PrintWriter(new FileOutputStream(121new File(logName), true));122} catch (FileNotFoundException e) {123throw new RuntimeException("Could not write loaded classes to log", e);124}125while (!done) {126Class[] allLoadedClasses = inst.getAllLoadedClasses();127int len = allLoadedClasses.length;128pw.println(" allLoadedClasses length: " + len);129for (int idx = 0; idx < len; idx++) {130Class cls = allLoadedClasses[idx];131pw.println(" " + idx + " " +132((cls != null) ? cls.getName() : "null"));133}134for (int idx = 0; idx < len; idx++) {135Class clazz = allLoadedClasses[idx];136if (clazz == null) {137pw.flush();138pw.close();139throw new RuntimeException("null class encountered");140}141final String name = clazz.getName();142if (name.contains("$$Lambda$") && name.contains("App")) {143if (inst.isModifiableClass(clazz)) {144pw.flush();145pw.close();146throw new RuntimeException ("Class should not be modifiable");147}148// Try to modify them anyway.149try {150System.out.println("retransform called for " + name);151inst.retransformClasses(clazz);152} catch(java.lang.instrument.UnmodifiableClassException t) {153System.out.println("PASSED: expecting UnmodifiableClassException");154t.printStackTrace();155}156try {157System.out.println("redefine called for " + name);158String newclass = "class Dummy {}";159byte[] bytecode = InMemoryJavaCompiler.compile("Dummy", newclass);160ClassDefinition cld = new ClassDefinition(clazz, bytecode);161inst.redefineClasses(new ClassDefinition[] { cld });162} catch(java.lang.instrument.UnmodifiableClassException t) {163System.out.println("PASSED: expecting UnmodifiableClassException");164t.printStackTrace();165} catch(java.lang.ClassNotFoundException e) {166pw.flush();167pw.close();168throw new RuntimeException ("ClassNotFoundException thrown");169}170done = true;171}172}173}174pw.flush();175pw.close();176}177178public static void main(String argv[]) throws InterruptedException, RuntimeException {179if (argv.length == 1 && argv[0].equals("buildagent")) {180buildAgent();181return;182}183184if (inst == null) {185throw new RuntimeException("Instrumentation object was null");186}187188new Thread() {189public void run() {190runTest();191}192}.start();193194// Test that NCDFE is not thrown for anonymous class:195// ModifyAnonymous$InstanceMethodCallSiteApp$$Lambda$18196try {197ModifyAnonymous test = new ModifyAnonymous();198InstanceMethodCallSiteApp.test();199} catch (NoClassDefFoundError e) {200throw new RuntimeException("FAILED: NoClassDefFoundError thrown for " + e.getMessage());201}202System.out.println("PASSED: NoClassDefFound error not thrown");203}204}205206207