1 /* 2 * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * @test 26 * @bug 6263319 27 * @summary test setNativeMethodPrefix 28 * @author Robert Field, Sun Microsystems 29 * 30 * @modules java.base/jdk.internal.org.objectweb.asm 31 * @run shell/timeout=240 MakeJAR2.sh NativeMethodPrefixAgent NativeMethodPrefixApp 'Can-Retransform-Classes: true' 'Can-Set-Native-Method-Prefix: true' 32 * @run main/othervm -javaagent:NativeMethodPrefixAgent.jar NativeMethodPrefixApp 33 */ 34 35 import java.lang.instrument.*; 36 import java.security.ProtectionDomain; 37 import java.io.*; 38 39 import asmlib.*; 40 41 class NativeMethodPrefixAgent { 42 43 static ClassFileTransformer t0, t1, t2; 44 static Instrumentation inst; 45 46 static class Tr implements ClassFileTransformer { 47 final String trname; 48 final int transformId; 49 50 Tr(int transformId) { 51 this.trname = "tr" + transformId; 52 this.transformId = transformId; 53 } 54 55 public byte[] 56 transform( 57 ClassLoader loader, 58 String className, 59 Class<?> classBeingRedefined, 60 ProtectionDomain protectionDomain, 61 byte[] classfileBuffer) { 62 boolean redef = classBeingRedefined != null; 63 System.out.println(trname + ": " + 64 (redef? "Retransforming " : "Loading ") + className); 65 if (className != null) { 66 try { 67 byte[] newcf = Instrumentor.instrFor(classfileBuffer) 68 .addNativeMethodTrackingInjection( 69 "wrapped_" + trname + "_", 70 (h)->{ 71 h.push(h.getName()); 72 h.push(transformId); 73 h.invokeStatic("bootreporter/StringIdCallbackReporter", "tracker", "(Ljava/lang/String;I)V", false); 74 }) 75 .apply(); 76 /*** debugging ... 77 if (newcf != null) { 78 String fname = trname + (redef?"_redef" : "") + "/" + className; 79 System.err.println("dumping to: " + fname); 80 write_buffer(fname + "_before.class", classfileBuffer); 81 write_buffer(fname + "_instr.class", newcf); 82 } 83 ***/ 84 85 return redef? null : newcf; 86 } catch (Throwable ex) { 87 System.err.println("ERROR: Injection failure: " + ex); 88 ex.printStackTrace(); 89 System.err.println("Returning bad class file, to cause test failure"); 90 return new byte[0]; 91 } 92 } 93 return null; 94 } 95 96 } 97 98 // for debugging 99 static void write_buffer(String fname, byte[]buffer) { 100 try { 101 File f = new File(fname); 102 if (!f.getParentFile().exists()) { 103 f.getParentFile().mkdirs(); 104 } 105 try (FileOutputStream outStream = new FileOutputStream(f)) { 106 outStream.write(buffer, 0, buffer.length); 107 } 108 } catch (IOException ex) { 109 System.err.println("EXCEPTION in write_buffer: " + ex); 110 } 111 } 112 113 public static void 114 premain (String agentArgs, Instrumentation instArg) 115 throws IOException, IllegalClassFormatException, 116 ClassNotFoundException, UnmodifiableClassException { 117 inst = instArg; 118 System.out.println("Premain"); 119 120 t1 = new Tr(1); 121 t2 = new Tr(2); 122 t0 = new Tr(0); 123 inst.addTransformer(t1, true); 124 inst.addTransformer(t2, false); 125 inst.addTransformer(t0, true); 126 instArg.setNativeMethodPrefix(t0, "wrapped_tr0_"); 127 instArg.setNativeMethodPrefix(t1, "wrapped_tr1_"); 128 instArg.setNativeMethodPrefix(t2, "wrapped_tr2_"); 129 130 // warm up: cause load of transformer classes before used during class load 131 instArg.retransformClasses(Runtime.class); 132 } 133 }