< prev index next >

test/lib/jdk/test/lib/classloader/GeneratingClassLoader.java

Print this page
rev 50198 : [mq]: 8203491-1


   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 package utils;
  24 
  25 import java.io.*;
  26 import java.util.*;
  27 
  28 /**
  29  * Classloader that generates classes on the fly.
  30  *
  31  * This classloader can load classes with name starting with 'Class'. It will
  32  * use TemplateClass as template and will replace class name in the bytecode of
  33  * template class. It can be used for example to detect memory leaks in class
  34  * loading or to quickly fill PermGen.
  35  */
  36 class GeneratingClassLoader extends ClassLoader {



  37 
  38     public synchronized Class loadClass(String name) throws ClassNotFoundException {
  39         return loadClass(name, false);
  40     }
  41 
  42     public synchronized Class loadClass(String name, boolean resolve)
  43             throws ClassNotFoundException {
  44         Class c = findLoadedClass(name);
  45         if (c != null) {
  46             return c;
  47         }
  48         if (!name.startsWith(PREFIX)) {
  49             return super.loadClass(name, resolve);
  50         }
  51         if (name.length() != templateClassName.length()) {
  52             throw new ClassNotFoundException("Only can load classes with name.length() = " + getNameLength() + " got: '" + name + "' length: " + name.length());
  53         }
  54         byte[] bytecode = getPatchedByteCode(name);
  55         c = defineClass(name, bytecode, 0, bytecode.length);
  56         if (resolve) {
  57             resolveClass(c);
  58         }
  59         return c;
  60     }
  61 
  62     /**
  63      * Create generating class loader that will use class file for given class
  64      * from classpath as template.
  65      */
  66     GeneratingClassLoader(String templateClassName) {
  67         this.templateClassName = templateClassName;
  68         classPath = System.getProperty("java.class.path").split(File.pathSeparator);
  69         try {
  70             templateClassNameBytes = templateClassName.getBytes(encoding);
  71         } catch (UnsupportedEncodingException e) {
  72             throw new RuntimeException(e);
  73         }
  74     }
  75 
  76     /**
  77      * Create generating class loader that will use class file for
  78      * nsk.share.classload.TemplateClass as template.
  79      */
  80     GeneratingClassLoader() {
  81         this(TemplateClass.class.getName());
  82     }
  83 
  84     int getNameLength() {
  85         return templateClassName.length();
  86     }
  87 
  88     String getPrefix() {
  89         return PREFIX;
  90     }
  91 
  92     String getClassName(int number) {
  93         StringBuffer sb = new StringBuffer();
  94         sb.append(PREFIX);
  95         sb.append(number);
  96         int n = templateClassName.length() - sb.length();
  97         for (int i = 0; i < n; ++i) {
  98             sb.append("_");
  99         }
 100         return sb.toString();
 101     }
 102 
 103     private byte[] getPatchedByteCode(String name) throws ClassNotFoundException {
 104         try {
 105             byte[] bytecode = getByteCode();
 106             String fname = name.replace(".", File.separator);
 107             byte[] replaceBytes = fname.getBytes(encoding);
 108             for (int offset : offsets) {
 109                 for (int i = 0; i < replaceBytes.length; ++i) {
 110                     bytecode[offset + i] = replaceBytes[i];
 111                 }
 112             }


 166                             break;
 167                         }
 168                         i++;
 169                     }
 170                     if (i == bytecode.length) {
 171                         break;
 172                     }
 173                     offsets.add(new Integer(i));
 174                     i++;
 175                 }
 176             } catch (UnsupportedEncodingException e) {
 177                 throw new RuntimeException(e);
 178             }
 179             this.offsets = new int[offsets.size()];
 180             for (int i = 0; i < offsets.size(); ++i) {
 181                 this.offsets[i] = offsets.get(i).intValue();
 182             }
 183         }
 184     }
 185 
 186     static final String DEFAULT_CLASSNAME = TemplateClass.class.getName();
 187     static final String PREFIX = "Class";
 188 
 189     private final String[] classPath;
 190     private byte[] bytecode;
 191     private int[] offsets;
 192     private final String encoding = "UTF8";
 193     private final String templateClassName;
 194     private final byte[] templateClassNameBytes;
 195 }


   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 package jdk.test.lib.classloader;
  24 
  25 import java.io.*;
  26 import java.util.*;
  27 
  28 /**
  29  * Classloader that generates classes on the fly.
  30  *
  31  * This classloader can load classes with name starting with 'Class'. It will
  32  * use TemplateClass as template and will replace class name in the bytecode of
  33  * template class. It can be used for example to detect memory leaks in class
  34  * loading or to quickly fill Metaspace.
  35  */
  36 class TemplateClass {
  37 }
  38 
  39 public class GeneratingClassLoader extends ClassLoader {
  40 
  41     public synchronized Class loadClass(String name) throws ClassNotFoundException {
  42         return loadClass(name, false);
  43     }
  44 
  45     public synchronized Class loadClass(String name, boolean resolve)
  46             throws ClassNotFoundException {
  47         Class c = findLoadedClass(name);
  48         if (c != null) {
  49             return c;
  50         }
  51         if (!name.startsWith(PREFIX)) {
  52             return super.loadClass(name, resolve);
  53         }
  54         if (name.length() != templateClassName.length()) {
  55             throw new ClassNotFoundException("Only can load classes with name.length() = " + getNameLength() + " got: '" + name + "' length: " + name.length());
  56         }
  57         byte[] bytecode = getPatchedByteCode(name);
  58         c = defineClass(name, bytecode, 0, bytecode.length);
  59         if (resolve) {
  60             resolveClass(c);
  61         }
  62         return c;
  63     }
  64 
  65     /**
  66      * Create generating class loader that will use class file for given class
  67      * from classpath as template.
  68      */
  69     public GeneratingClassLoader(String templateClassName) {
  70         this.templateClassName = templateClassName;
  71         classPath = System.getProperty("java.class.path").split(File.pathSeparator);
  72         try {
  73             templateClassNameBytes = templateClassName.getBytes(encoding);
  74         } catch (UnsupportedEncodingException e) {
  75             throw new RuntimeException(e);
  76         }
  77     }
  78 
  79     /**
  80      * Create generating class loader that will use class file for
  81      * nsk.share.classload.TemplateClass as template.
  82      */
  83     public GeneratingClassLoader() {
  84         this(TemplateClass.class.getName());
  85     }
  86 
  87     public int getNameLength() {
  88         return templateClassName.length();
  89     }
  90 
  91     String getPrefix() {
  92         return PREFIX;
  93     }
  94 
  95     public String getClassName(int number) {
  96         StringBuffer sb = new StringBuffer();
  97         sb.append(PREFIX);
  98         sb.append(number);
  99         int n = templateClassName.length() - sb.length();
 100         for (int i = 0; i < n; ++i) {
 101             sb.append("_");
 102         }
 103         return sb.toString();
 104     }
 105 
 106     private byte[] getPatchedByteCode(String name) throws ClassNotFoundException {
 107         try {
 108             byte[] bytecode = getByteCode();
 109             String fname = name.replace(".", File.separator);
 110             byte[] replaceBytes = fname.getBytes(encoding);
 111             for (int offset : offsets) {
 112                 for (int i = 0; i < replaceBytes.length; ++i) {
 113                     bytecode[offset + i] = replaceBytes[i];
 114                 }
 115             }


 169                             break;
 170                         }
 171                         i++;
 172                     }
 173                     if (i == bytecode.length) {
 174                         break;
 175                     }
 176                     offsets.add(new Integer(i));
 177                     i++;
 178                 }
 179             } catch (UnsupportedEncodingException e) {
 180                 throw new RuntimeException(e);
 181             }
 182             this.offsets = new int[offsets.size()];
 183             for (int i = 0; i < offsets.size(); ++i) {
 184                 this.offsets[i] = offsets.get(i).intValue();
 185             }
 186         }
 187     }
 188 
 189     public static final String DEFAULT_CLASSNAME = TemplateClass.class.getName();
 190     static final String PREFIX = "Class";
 191 
 192     private final String[] classPath;
 193     private byte[] bytecode;
 194     private int[] offsets;
 195     private final String encoding = "UTF8";
 196     private final String templateClassName;
 197     private final byte[] templateClassNameBytes;
 198 }
< prev index next >