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