1 /*
   2  * Copyright (c) 2003, 2016, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.instrument;
  27 
  28 import java.lang.reflect.Module;
  29 import java.security.AccessController;
  30 import java.security.PrivilegedAction;
  31 import java.security.ProtectionDomain;
  32 
  33 /*
  34  * Copyright 2003 Wily Technology, Inc.
  35  */
  36 
  37 /**
  38  * A transformer of class files. An agent registers an implementation of this
  39  * interface using the {@link Instrumentation#addTransformer addTransformer}
  40  * method so that the transformer's {@link
  41  * ClassFileTransformer#transform(Module,ClassLoader,String,Class,ProtectionDomain,byte[])
  42  * transform} method is invoked when classes are loaded,
  43  * {@link Instrumentation#redefineClasses redefined}, or
  44  * {@link Instrumentation#retransformClasses retransformed}. The implementation
  45  * should override one of the {@code transform} methods defined here.
  46  * Transformers are invoked before the class is defined by the Java virtual
  47  * machine.
  48  *
  49  * <P>
  50  * There are two kinds of transformers, determined by the <code>canRetransform</code>
  51  * parameter of
  52  * {@link java.lang.instrument.Instrumentation#addTransformer(ClassFileTransformer,boolean)}:
  53  *  <ul>
  54  *    <li><i>retransformation capable</i> transformers that were added with
  55  *        <code>canRetransform</code> as true
  56  *    </li>
  57  *    <li><i>retransformation incapable</i> transformers that were added with
  58  *        <code>canRetransform</code> as false or where added with
  59  *        {@link java.lang.instrument.Instrumentation#addTransformer(ClassFileTransformer)}
  60  *    </li>
  61  *  </ul>
  62  *
  63  * <P>
  64  * Once a transformer has been registered with
  65  * {@link java.lang.instrument.Instrumentation#addTransformer(ClassFileTransformer,boolean)
  66  * addTransformer},
  67  * the transformer will be called for every new class definition and every class redefinition.
  68  * Retransformation capable transformers will also be called on every class retransformation.
  69  * The request for a new class definition is made with
  70  * {@link java.lang.ClassLoader#defineClass ClassLoader.defineClass}
  71  * or its native equivalents.
  72  * The request for a class redefinition is made with
  73  * {@link java.lang.instrument.Instrumentation#redefineClasses Instrumentation.redefineClasses}
  74  * or its native equivalents.
  75  * The request for a class retransformation is made with
  76  * {@link java.lang.instrument.Instrumentation#retransformClasses Instrumentation.retransformClasses}
  77  * or its native equivalents.
  78  * The transformer is called during the processing of the request, before the class file bytes
  79  * have been verified or applied.
  80  * When there are multiple transformers, transformations are composed by chaining the
  81  * <code>transform</code> calls.
  82  * That is, the byte array returned by one call to <code>transform</code> becomes the input
  83  * (via the <code>classfileBuffer</code> parameter) to the next call.
  84  *
  85  * <P>
  86  * Transformations are applied in the following order:
  87  *  <ul>
  88  *    <li>Retransformation incapable transformers
  89  *    </li>
  90  *    <li>Retransformation incapable native transformers
  91  *    </li>
  92  *    <li>Retransformation capable transformers
  93  *    </li>
  94  *    <li>Retransformation capable native transformers
  95  *    </li>
  96  *  </ul>
  97  *
  98  * <P>
  99  * For retransformations, the retransformation incapable transformers are not
 100  * called, instead the result of the previous transformation is reused.
 101  * In all other cases, this method is called.
 102  * Within each of these groupings, transformers are called in the order registered.
 103  * Native transformers are provided by the <code>ClassFileLoadHook</code> event
 104  * in the Java Virtual Machine Tool Interface).
 105  *
 106  * <P>
 107  * The input (via the <code>classfileBuffer</code> parameter) to the first
 108  * transformer is:
 109  *  <ul>
 110  *    <li>for new class definition,
 111  *        the bytes passed to <code>ClassLoader.defineClass</code>
 112  *    </li>
 113  *    <li>for class redefinition,
 114  *        <code>definitions.getDefinitionClassFile()</code> where
 115  *        <code>definitions</code> is the parameter to
 116  *        {@link java.lang.instrument.Instrumentation#redefineClasses
 117  *         Instrumentation.redefineClasses}
 118  *    </li>
 119  *    <li>for class retransformation,
 120  *         the bytes passed to the new class definition or, if redefined,
 121  *         the last redefinition, with all transformations made by retransformation
 122  *         incapable transformers reapplied automatically and unaltered;
 123  *         for details see
 124  *         {@link java.lang.instrument.Instrumentation#retransformClasses
 125  *          Instrumentation.retransformClasses}
 126  *    </li>
 127  *  </ul>
 128  *
 129  * <P>
 130  * If the implementing method determines that no transformations are needed,
 131  * it should return <code>null</code>.
 132  * Otherwise, it should create a new <code>byte[]</code> array,
 133  * copy the input <code>classfileBuffer</code> into it,
 134  * along with all desired transformations, and return the new array.
 135  * The input <code>classfileBuffer</code> must not be modified.
 136  *
 137  * <P>
 138  * In the retransform and redefine cases,
 139  * the transformer must support the redefinition semantics:
 140  * if a class that the transformer changed during initial definition is later
 141  * retransformed or redefined, the
 142  * transformer must insure that the second class output class file is a legal
 143  * redefinition of the first output class file.
 144  *
 145  * <P>
 146  * If the transformer throws an exception (which it doesn't catch),
 147  * subsequent transformers will still be called and the load, redefine
 148  * or retransform will still be attempted.
 149  * Thus, throwing an exception has the same effect as returning <code>null</code>.
 150  * To prevent unexpected behavior when unchecked exceptions are generated
 151  * in transformer code, a transformer can catch <code>Throwable</code>.
 152  * If the transformer believes the <code>classFileBuffer</code> does not
 153  * represent a validly formatted class file, it should throw
 154  * an <code>IllegalClassFormatException</code>;
 155  * while this has the same effect as returning null. it facilitates the
 156  * logging or debugging of format corruptions.
 157  *
 158  * <P>
 159  * Note the term <i>class file</i> is used as defined in section 3.1 of
 160  * <cite>The Java&trade; Virtual Machine Specification</cite>, to mean a
 161  * sequence of bytes in class file format, whether or not they reside in a
 162  * file.
 163  *
 164  * @see     java.lang.instrument.Instrumentation
 165  * @since   1.5
 166  */
 167 
 168 public interface ClassFileTransformer {
 169 
 170     /**
 171      * Transforms the given class file and returns a new replacement class file.
 172      * This method is invoked when the {@link Module Module} bearing {@link
 173      * ClassFileTransformer#transform(Module,ClassLoader,String,Class,ProtectionDomain,byte[])
 174      * transform} is not overridden.
 175      *
 176      * @implSpec The default implementation returns null.
 177      *
 178      * @param loader                the defining loader of the class to be transformed,
 179      *                              may be {@code null} if the bootstrap loader
 180      * @param className             the name of the class in the internal form of fully
 181      *                              qualified class and interface names as defined in
 182      *                              <i>The Java Virtual Machine Specification</i>.
 183      *                              For example, <code>"java/util/List"</code>.
 184      * @param classBeingRedefined   if this is triggered by a redefine or retransform,
 185      *                              the class being redefined or retransformed;
 186      *                              if this is a class load, {@code null}
 187      * @param protectionDomain      the protection domain of the class being defined or redefined
 188      * @param classfileBuffer       the input byte buffer in class file format - must not be modified
 189      *
 190      * @throws IllegalClassFormatException
 191      *         if the input does not represent a well-formed class file
 192      * @return a well-formed class file buffer (the result of the transform),
 193      *         or {@code null} if no transform is performed
 194      */
 195     default byte[]
 196     transform(  ClassLoader         loader,
 197                 String              className,
 198                 Class<?>            classBeingRedefined,
 199                 ProtectionDomain    protectionDomain,
 200                 byte[]              classfileBuffer)
 201         throws IllegalClassFormatException {
 202         return null;
 203     }
 204 
 205 
 206     /**
 207      * Transforms the given class file and returns a new replacement class file.
 208      *
 209      * @implSpec The default implementation of this method invokes the
 210      * {@link #transform(ClassLoader,String,Class,ProtectionDomain,byte[]) transform}
 211      * method.
 212      *
 213      * @param module                the module of the class to be transformed
 214      * @param loader                the defining loader of the class to be transformed,
 215      *                              may be {@code null} if the bootstrap loader
 216      * @param className             the name of the class in the internal form of fully
 217      *                              qualified class and interface names as defined in
 218      *                              <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 redefined
 224      * @param classfileBuffer       the input byte buffer in class file format - must not be modified
 225      *
 226      * @throws IllegalClassFormatException
 227      *         if the input does not represent a well-formed class file
 228      * @return a well-formed class file buffer (the result of the transform),
 229      *         or {@code null} if no transform is performed
 230      *
 231      * @since  9
 232      * @spec JPMS
 233      */
 234     default byte[]
 235     transform(  Module              module,
 236                 ClassLoader         loader,
 237                 String              className,
 238                 Class<?>            classBeingRedefined,
 239                 ProtectionDomain    protectionDomain,
 240                 byte[]              classfileBuffer)
 241         throws IllegalClassFormatException {
 242 
 243         // invoke the legacy transform method
 244         return transform(loader,
 245                          className,
 246                          classBeingRedefined,
 247                          protectionDomain,
 248                          classfileBuffer);
 249     }
 250 }