Path: blob/master/src/java.instrument/share/classes/java/lang/instrument/ClassFileTransformer.java
41159 views
/*1* Copyright (c) 2003, 2016, 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. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.lang.instrument;2627import java.security.AccessController;28import java.security.PrivilegedAction;29import java.security.ProtectionDomain;3031/*32* Copyright 2003 Wily Technology, Inc.33*/3435/**36* A transformer of class files. An agent registers an implementation of this37* interface using the {@link Instrumentation#addTransformer addTransformer}38* method so that the transformer's {@link39* ClassFileTransformer#transform(Module,ClassLoader,String,Class,ProtectionDomain,byte[])40* transform} method is invoked when classes are loaded,41* {@link Instrumentation#redefineClasses redefined}, or42* {@link Instrumentation#retransformClasses retransformed}. The implementation43* should override one of the {@code transform} methods defined here.44* Transformers are invoked before the class is defined by the Java virtual45* machine.46*47* <P>48* There are two kinds of transformers, determined by the <code>canRetransform</code>49* parameter of50* {@link java.lang.instrument.Instrumentation#addTransformer(ClassFileTransformer,boolean)}:51* <ul>52* <li><i>retransformation capable</i> transformers that were added with53* <code>canRetransform</code> as true54* </li>55* <li><i>retransformation incapable</i> transformers that were added with56* <code>canRetransform</code> as false or where added with57* {@link java.lang.instrument.Instrumentation#addTransformer(ClassFileTransformer)}58* </li>59* </ul>60*61* <P>62* Once a transformer has been registered with63* {@link java.lang.instrument.Instrumentation#addTransformer(ClassFileTransformer,boolean)64* addTransformer},65* the transformer will be called for every new class definition and every class redefinition.66* Retransformation capable transformers will also be called on every class retransformation.67* The request for a new class definition is made with68* {@link java.lang.ClassLoader#defineClass ClassLoader.defineClass}69* or its native equivalents.70* The request for a class redefinition is made with71* {@link java.lang.instrument.Instrumentation#redefineClasses Instrumentation.redefineClasses}72* or its native equivalents.73* The request for a class retransformation is made with74* {@link java.lang.instrument.Instrumentation#retransformClasses Instrumentation.retransformClasses}75* or its native equivalents.76* The transformer is called during the processing of the request, before the class file bytes77* have been verified or applied.78* When there are multiple transformers, transformations are composed by chaining the79* <code>transform</code> calls.80* That is, the byte array returned by one call to <code>transform</code> becomes the input81* (via the <code>classfileBuffer</code> parameter) to the next call.82*83* <P>84* Transformations are applied in the following order:85* <ul>86* <li>Retransformation incapable transformers87* </li>88* <li>Retransformation incapable native transformers89* </li>90* <li>Retransformation capable transformers91* </li>92* <li>Retransformation capable native transformers93* </li>94* </ul>95*96* <P>97* For retransformations, the retransformation incapable transformers are not98* called, instead the result of the previous transformation is reused.99* In all other cases, this method is called.100* Within each of these groupings, transformers are called in the order registered.101* Native transformers are provided by the <code>ClassFileLoadHook</code> event102* in the Java Virtual Machine Tool Interface).103*104* <P>105* The input (via the <code>classfileBuffer</code> parameter) to the first106* transformer is:107* <ul>108* <li>for new class definition,109* the bytes passed to <code>ClassLoader.defineClass</code>110* </li>111* <li>for class redefinition,112* <code>definitions.getDefinitionClassFile()</code> where113* <code>definitions</code> is the parameter to114* {@link java.lang.instrument.Instrumentation#redefineClasses115* Instrumentation.redefineClasses}116* </li>117* <li>for class retransformation,118* the bytes passed to the new class definition or, if redefined,119* the last redefinition, with all transformations made by retransformation120* incapable transformers reapplied automatically and unaltered;121* for details see122* {@link java.lang.instrument.Instrumentation#retransformClasses123* Instrumentation.retransformClasses}124* </li>125* </ul>126*127* <P>128* If the implementing method determines that no transformations are needed,129* it should return <code>null</code>.130* Otherwise, it should create a new <code>byte[]</code> array,131* copy the input <code>classfileBuffer</code> into it,132* along with all desired transformations, and return the new array.133* The input <code>classfileBuffer</code> must not be modified.134*135* <P>136* In the retransform and redefine cases,137* the transformer must support the redefinition semantics:138* if a class that the transformer changed during initial definition is later139* retransformed or redefined, the140* transformer must insure that the second class output class file is a legal141* redefinition of the first output class file.142*143* <P>144* If the transformer throws an exception (which it doesn't catch),145* subsequent transformers will still be called and the load, redefine146* or retransform will still be attempted.147* Thus, throwing an exception has the same effect as returning <code>null</code>.148* To prevent unexpected behavior when unchecked exceptions are generated149* in transformer code, a transformer can catch <code>Throwable</code>.150* If the transformer believes the <code>classFileBuffer</code> does not151* represent a validly formatted class file, it should throw152* an <code>IllegalClassFormatException</code>;153* while this has the same effect as returning null. it facilitates the154* logging or debugging of format corruptions.155*156* <P>157* Note the term <i>class file</i> is used as defined in section 3.1 of158* <cite>The Java Virtual Machine Specification</cite>, to mean a159* sequence of bytes in class file format, whether or not they reside in a160* file.161*162* @see java.lang.instrument.Instrumentation163* @since 1.5164*/165166public interface ClassFileTransformer {167168/**169* Transforms the given class file and returns a new replacement class file.170* This method is invoked when the {@link Module Module} bearing {@link171* ClassFileTransformer#transform(Module,ClassLoader,String,Class,ProtectionDomain,byte[])172* transform} is not overridden.173*174* @implSpec The default implementation returns null.175*176* @param loader the defining loader of the class to be transformed,177* may be {@code null} if the bootstrap loader178* @param className the name of the class in the internal form of fully179* qualified class and interface names as defined in180* <i>The Java Virtual Machine Specification</i>.181* For example, <code>"java/util/List"</code>.182* @param classBeingRedefined if this is triggered by a redefine or retransform,183* the class being redefined or retransformed;184* if this is a class load, {@code null}185* @param protectionDomain the protection domain of the class being defined or redefined186* @param classfileBuffer the input byte buffer in class file format - must not be modified187*188* @throws IllegalClassFormatException189* if the input does not represent a well-formed class file190* @return a well-formed class file buffer (the result of the transform),191* or {@code null} if no transform is performed192*193* @revised 9194*/195default byte[]196transform( ClassLoader loader,197String className,198Class<?> classBeingRedefined,199ProtectionDomain protectionDomain,200byte[] classfileBuffer)201throws IllegalClassFormatException {202return null;203}204205206/**207* Transforms the given class file and returns a new replacement class file.208*209* @implSpec The default implementation of this method invokes the210* {@link #transform(ClassLoader,String,Class,ProtectionDomain,byte[]) transform}211* method.212*213* @param module the module of the class to be transformed214* @param loader the defining loader of the class to be transformed,215* may be {@code null} if the bootstrap loader216* @param className the name of the class in the internal form of fully217* qualified class and interface names as defined in218* <i>The Java Virtual Machine Specification</i>.219* For example, <code>"java/util/List"</code>.220* @param classBeingRedefined if this is triggered by a redefine or retransform,221* the class being redefined or retransformed;222* if this is a class load, {@code null}223* @param protectionDomain the protection domain of the class being defined or redefined224* @param classfileBuffer the input byte buffer in class file format - must not be modified225*226* @throws IllegalClassFormatException227* if the input does not represent a well-formed class file228* @return a well-formed class file buffer (the result of the transform),229* or {@code null} if no transform is performed230*231* @since 9232*/233default byte[]234transform( Module module,235ClassLoader loader,236String className,237Class<?> classBeingRedefined,238ProtectionDomain protectionDomain,239byte[] classfileBuffer)240throws IllegalClassFormatException {241242// invoke the legacy transform method243return transform(loader,244className,245classBeingRedefined,246protectionDomain,247classfileBuffer);248}249}250251252