jdk/test/javax/management/remote/mandatory/loading/SingleClassLoader.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 2003 Sun Microsystems, Inc.  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.
       
     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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  */
       
    23 
       
    24 /*
       
    25  * build         @BUILD_TAG_PLACEHOLDER@
       
    26  *
       
    27  * @COPYRIGHT_MINI_LEGAL_NOTICE_PLACEHOLDER@
       
    28  */
       
    29 
       
    30 import java.io.*;
       
    31 import java.lang.reflect.*;
       
    32 
       
    33 /*
       
    34   ClassLoader that knows how to fabricate exactly one class.  The name
       
    35   of the class is defined by the parameter singleClassName.  When
       
    36   asked to load a class, this loader first delegates to its parent as
       
    37   usual, then, if that doesn't find the class and if the name is the
       
    38   same as singleClassName, the class is fabricated.  It is a public
       
    39   class with no fields or methods and a single public no-arg
       
    40   constructor that simply calls its parent's no-arg constructor.  This
       
    41   means that the parent must have a public or protected no-arg
       
    42   constructor.
       
    43  */
       
    44 public class SingleClassLoader extends ClassLoader {
       
    45     SingleClassLoader(String singleClassName, Class superclass,
       
    46                       ClassLoader parent) {
       
    47         super(parent);
       
    48 
       
    49         Constructor superConstr;
       
    50         try {
       
    51             superConstr = superclass.getDeclaredConstructor(new Class[0]);
       
    52         } catch (NoSuchMethodException e) {
       
    53             throw new IllegalArgumentException("Superclass must have no-arg " +
       
    54                                                "constructor");
       
    55         }
       
    56         int superConstrMods = superConstr.getModifiers();
       
    57         if ((superConstrMods & (Modifier.PUBLIC|Modifier.PROTECTED)) == 0) {
       
    58             final String msg =
       
    59                 "Superclass no-arg constructor must be public or protected";
       
    60             throw new IllegalArgumentException(msg);
       
    61         }
       
    62 
       
    63         this.singleClassName = singleClassName;
       
    64         final Class c;
       
    65         try {
       
    66             c = makeClass(superclass);
       
    67         } catch (IOException e) {
       
    68             throw new RuntimeException(e.toString());
       
    69         }
       
    70         this.singleClass = c;
       
    71     }
       
    72 
       
    73     private Class makeClass(Class superclass) throws IOException {
       
    74         final String superName = superclass.getName();
       
    75 
       
    76         ByteArrayOutputStream bout = new ByteArrayOutputStream();
       
    77         dout = new DataOutputStream(bout);
       
    78 
       
    79         String thisNameInternal = singleClassName.replace('.', '/');
       
    80         String superNameInternal = superName.replace('.', '/');
       
    81 
       
    82         dout.writeInt(0xcafebabe); // magic
       
    83         dout.writeInt(0x0003002d); // major 45 minor 3
       
    84         dout.writeShort(10);       // cpool count (incl virtual 0 element)
       
    85 
       
    86         cpoolIndex = 1;
       
    87 
       
    88         int thisNameConst = writeUTFConst(thisNameInternal);
       
    89         int thisClassConst = writeClassConst(thisNameConst);
       
    90         int superNameConst = writeUTFConst(superNameInternal);
       
    91         int superClassConst = writeClassConst(superNameConst);
       
    92         int initNameConst = writeUTFConst("<init>");
       
    93         int voidNoArgSigConst = writeUTFConst("()V");
       
    94         int codeNameConst = writeUTFConst("Code");
       
    95         int superConstructorNameAndTypeConst =
       
    96             writeNameAndTypeConst(initNameConst, voidNoArgSigConst);
       
    97         int superConstructorMethodRefConst =
       
    98             writeMethodRefConst(superClassConst,
       
    99                                 superConstructorNameAndTypeConst);
       
   100 
       
   101         dout.writeShort(Modifier.PUBLIC | 0x20 /*SUPER*/);
       
   102         dout.writeShort(thisClassConst);
       
   103         dout.writeShort(superClassConst);
       
   104         dout.writeInt(0);   // n interfaces, n fields
       
   105         dout.writeShort(1); // n methods
       
   106 
       
   107         // <init> method
       
   108         dout.writeShort(Modifier.PUBLIC);
       
   109         dout.writeShort(initNameConst);
       
   110         dout.writeShort(voidNoArgSigConst);
       
   111         dout.writeShort(1); // attr count
       
   112 
       
   113         // Code attribute
       
   114         dout.writeShort(codeNameConst);
       
   115         dout.writeInt(17);   // len
       
   116         dout.writeShort(1);  // max stack
       
   117         dout.writeShort(1);  // max locals
       
   118         dout.writeInt(5);    // code len
       
   119         dout.writeByte(42);  // aload_0
       
   120         dout.writeByte(183); // invokespecial
       
   121         dout.writeShort(superConstructorMethodRefConst);
       
   122         dout.writeByte(177); // return
       
   123 
       
   124         dout.writeShort(0);  // 0 catches
       
   125 
       
   126         dout.writeShort(0);  // 0 method attrs
       
   127 
       
   128         dout.writeShort(0);  // 0 class attrs
       
   129 
       
   130         dout.close();
       
   131         byte[] classBytes = bout.toByteArray();
       
   132 
       
   133         dout = null;
       
   134 
       
   135         return
       
   136             defineClass(singleClassName, classBytes, 0, classBytes.length);
       
   137     }
       
   138 
       
   139     protected Class findClass(String name) throws ClassNotFoundException {
       
   140         if (name.equals(singleClassName))
       
   141             return singleClass;
       
   142         else
       
   143             throw new ClassNotFoundException(name);
       
   144     }
       
   145 
       
   146     private int writeUTFConst(String s) throws IOException {
       
   147         dout.writeByte(1);
       
   148         dout.writeUTF(s);
       
   149         return cpoolIndex++;
       
   150     }
       
   151 
       
   152     private int writeClassConst(int nameIndex) throws IOException {
       
   153         dout.writeByte(7);
       
   154         dout.writeShort((short) nameIndex);
       
   155         return cpoolIndex++;
       
   156     }
       
   157 
       
   158     private int writeNameAndTypeConst(int nameIndex, int typeIndex)
       
   159             throws IOException {
       
   160         dout.writeByte(12);
       
   161         dout.writeShort((short) nameIndex);
       
   162         dout.writeShort((short) typeIndex);
       
   163         return cpoolIndex++;
       
   164     }
       
   165 
       
   166     private int writeMethodRefConst(int classIndex, int nameAndTypeIndex)
       
   167             throws IOException {
       
   168         dout.writeByte(10);
       
   169         dout.writeShort((short) classIndex);
       
   170         dout.writeShort((short) nameAndTypeIndex);
       
   171         return cpoolIndex++;
       
   172     }
       
   173 
       
   174     private final String singleClassName;
       
   175     private final Class singleClass;
       
   176 
       
   177     private DataOutputStream dout;
       
   178     private int cpoolIndex;
       
   179 }