< prev index next >

src/java.instrument/share/classes/sun/instrument/TransformerManager.java

Print this page
rev 49703 : 8200559: Java agents doing instrumentation need a means to define auxiliary classes
Reviewed-by: duke


   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 sun.instrument;
  27 
  28 import java.lang.instrument.Instrumentation;
  29 import java.lang.instrument.ClassFileTransformer;
  30 import java.security.ProtectionDomain;
  31 
  32 /*
  33  * Copyright 2003 Wily Technology, Inc.
  34  */
  35 
  36 /**
  37  * Support class for the InstrumentationImpl. Manages the list of registered transformers.
  38  * Keeps everything in the right order, deals with sync of the list,
  39  * and actually does the calling of the transformers.
  40  */
  41 public class TransformerManager
  42 {
  43     private class TransformerInfo {
  44         final ClassFileTransformer  mTransformer;
  45         String                      mPrefix;
  46 
  47         TransformerInfo(ClassFileTransformer transformer) {
  48             mTransformer = transformer;


 158 
 159     // This function doesn't actually snapshot anything, but should be
 160     // used to set a local variable, which will snapshot the transformer
 161     // list because of the copying semantics of mTransformerList (see
 162     // the comment for mTransformerList).
 163     private TransformerInfo[]
 164     getSnapshotTransformerList() {
 165         return mTransformerList;
 166     }
 167 
 168     public byte[]
 169     transform(  Module              module,
 170                 ClassLoader         loader,
 171                 String              classname,
 172                 Class<?>            classBeingRedefined,
 173                 ProtectionDomain    protectionDomain,
 174                 byte[]              classfileBuffer) {
 175         boolean someoneTouchedTheBytecode = false;
 176 
 177         TransformerInfo[]  transformerList = getSnapshotTransformerList();
 178 
 179         byte[]  bufferToUse = classfileBuffer;
 180 

 181         // order matters, gotta run 'em in the order they were added
 182         for ( int x = 0; x < transformerList.length; x++ ) {
 183             TransformerInfo         transformerInfo = transformerList[x];
 184             ClassFileTransformer    transformer = transformerInfo.transformer();
 185             byte[]                  transformedBytes = null;
 186 
 187             try {
 188                 transformedBytes = transformer.transform(   module,

 189                                                             loader,
 190                                                             classname,
 191                                                             classBeingRedefined,
 192                                                             protectionDomain,
 193                                                             bufferToUse);
 194             }
 195             catch (Throwable t) {
 196                 // don't let any one transformer mess it up for the others.
 197                 // This is where we need to put some logging. What should go here? FIXME
 198             }
 199 
 200             if ( transformedBytes != null ) {
 201                 someoneTouchedTheBytecode = true;
 202                 bufferToUse = transformedBytes;
 203             }
 204         }


 205 
 206         // if someone modified it, return the modified buffer.
 207         // otherwise return null to mean "no transforms occurred"
 208         byte [] result;
 209         if ( someoneTouchedTheBytecode ) {
 210             result = bufferToUse;
 211         }
 212         else {
 213             result = null;
 214         }
 215 
 216         return result;
 217     }
 218 
 219 
 220     int
 221     getTransformerCount() {
 222         TransformerInfo[]  transformerList = getSnapshotTransformerList();
 223         return transformerList.length;
 224     }
 225 
 226     boolean
 227     setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) {
 228         TransformerInfo[]  transformerList = getSnapshotTransformerList();
 229 
 230         for ( int x = 0; x < transformerList.length; x++ ) {
 231             TransformerInfo         transformerInfo = transformerList[x];
 232             ClassFileTransformer    aTransformer = transformerInfo.transformer();
 233 
 234             if ( aTransformer == transformer ) {
 235                 transformerInfo.setPrefix(prefix);
 236                 return true;
 237             }
 238         }
 239         return false;


   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 sun.instrument;
  27 

  28 import java.lang.instrument.ClassFileTransformer;
  29 import java.security.ProtectionDomain;
  30 
  31 /*
  32  * Copyright 2003 Wily Technology, Inc.
  33  */
  34 
  35 /**
  36  * Support class for the InstrumentationImpl. Manages the list of registered transformers.
  37  * Keeps everything in the right order, deals with sync of the list,
  38  * and actually does the calling of the transformers.
  39  */
  40 public class TransformerManager
  41 {
  42     private class TransformerInfo {
  43         final ClassFileTransformer  mTransformer;
  44         String                      mPrefix;
  45 
  46         TransformerInfo(ClassFileTransformer transformer) {
  47             mTransformer = transformer;


 157 
 158     // This function doesn't actually snapshot anything, but should be
 159     // used to set a local variable, which will snapshot the transformer
 160     // list because of the copying semantics of mTransformerList (see
 161     // the comment for mTransformerList).
 162     private TransformerInfo[]
 163     getSnapshotTransformerList() {
 164         return mTransformerList;
 165     }
 166 
 167     public byte[]
 168     transform(  Module              module,
 169                 ClassLoader         loader,
 170                 String              classname,
 171                 Class<?>            classBeingRedefined,
 172                 ProtectionDomain    protectionDomain,
 173                 byte[]              classfileBuffer) {
 174         boolean someoneTouchedTheBytecode = false;
 175 
 176         TransformerInfo[] transformerList = getSnapshotTransformerList();

 177         byte[] bufferToUse = classfileBuffer;
 178 
 179         try (CloseableClassDefiner classDefiner = new CloseableClassDefiner(classname, loader, protectionDomain)) {
 180             // order matters, gotta run 'em in the order they were added
 181             for (int x = 0; x < transformerList.length; x++) {
 182                 TransformerInfo transformerInfo = transformerList[x];
 183                 ClassFileTransformer transformer = transformerInfo.transformer();
 184                 byte[] transformedBytes = null;

 185                 try {
 186                     transformedBytes = transformer.transform(classDefiner,
 187                                                              module,
 188                                                              loader,
 189                                                              classname,
 190                                                              classBeingRedefined,
 191                                                              protectionDomain,
 192                                                              bufferToUse);
 193                 } catch (Throwable t) {

 194                     // don't let any one transformer mess it up for the others.
 195                     // This is where we need to put some logging. What should go here? FIXME
 196                 }
 197 
 198                 if (transformedBytes != null) {
 199                     someoneTouchedTheBytecode = true;
 200                     bufferToUse = transformedBytes;
 201                 }
 202             }
 203         }
 204 
 205 
 206         // if someone modified it, return the modified buffer.
 207         // otherwise return null to mean "no transforms occurred"
 208         byte [] result;
 209         if ( someoneTouchedTheBytecode ) {
 210             result = bufferToUse;
 211         }
 212         else {
 213             result = null;
 214         }
 215 
 216         return result;
 217     }
 218 

 219     int
 220     getTransformerCount() {
 221         TransformerInfo[]  transformerList = getSnapshotTransformerList();
 222         return transformerList.length;
 223     }
 224 
 225     boolean
 226     setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) {
 227         TransformerInfo[]  transformerList = getSnapshotTransformerList();
 228 
 229         for ( int x = 0; x < transformerList.length; x++ ) {
 230             TransformerInfo         transformerInfo = transformerList[x];
 231             ClassFileTransformer    aTransformer = transformerInfo.transformer();
 232 
 233             if ( aTransformer == transformer ) {
 234                 transformerInfo.setPrefix(prefix);
 235                 return true;
 236             }
 237         }
 238         return false;
< prev index next >