Path: blob/master/test/jdk/javax/management/remote/mandatory/loading/SingleClassLoader.java
41159 views
/*1* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* build @BUILD_TAG_PLACEHOLDER@25*26* @COPYRIGHT_MINI_LEGAL_NOTICE_PLACEHOLDER@27*/2829import java.io.*;30import java.lang.reflect.*;3132/*33ClassLoader that knows how to fabricate exactly one class. The name34of the class is defined by the parameter singleClassName. When35asked to load a class, this loader first delegates to its parent as36usual, then, if that doesn't find the class and if the name is the37same as singleClassName, the class is fabricated. It is a public38class with no fields or methods and a single public no-arg39constructor that simply calls its parent's no-arg constructor. This40means that the parent must have a public or protected no-arg41constructor.42*/43public class SingleClassLoader extends ClassLoader {44SingleClassLoader(String singleClassName, Class superclass,45ClassLoader parent) {46super(parent);4748Constructor superConstr;49try {50superConstr = superclass.getDeclaredConstructor(new Class[0]);51} catch (NoSuchMethodException e) {52throw new IllegalArgumentException("Superclass must have no-arg " +53"constructor");54}55int superConstrMods = superConstr.getModifiers();56if ((superConstrMods & (Modifier.PUBLIC|Modifier.PROTECTED)) == 0) {57final String msg =58"Superclass no-arg constructor must be public or protected";59throw new IllegalArgumentException(msg);60}6162this.singleClassName = singleClassName;63final Class c;64try {65c = makeClass(superclass);66} catch (IOException e) {67throw new RuntimeException(e.toString());68}69this.singleClass = c;70}7172private Class makeClass(Class superclass) throws IOException {73final String superName = superclass.getName();7475ByteArrayOutputStream bout = new ByteArrayOutputStream();76dout = new DataOutputStream(bout);7778String thisNameInternal = singleClassName.replace('.', '/');79String superNameInternal = superName.replace('.', '/');8081dout.writeInt(0xcafebabe); // magic82dout.writeInt(0x0003002d); // major 45 minor 383dout.writeShort(10); // cpool count (incl virtual 0 element)8485cpoolIndex = 1;8687int thisNameConst = writeUTFConst(thisNameInternal);88int thisClassConst = writeClassConst(thisNameConst);89int superNameConst = writeUTFConst(superNameInternal);90int superClassConst = writeClassConst(superNameConst);91int initNameConst = writeUTFConst("<init>");92int voidNoArgSigConst = writeUTFConst("()V");93int codeNameConst = writeUTFConst("Code");94int superConstructorNameAndTypeConst =95writeNameAndTypeConst(initNameConst, voidNoArgSigConst);96int superConstructorMethodRefConst =97writeMethodRefConst(superClassConst,98superConstructorNameAndTypeConst);99100dout.writeShort(Modifier.PUBLIC | 0x20 /*SUPER*/);101dout.writeShort(thisClassConst);102dout.writeShort(superClassConst);103dout.writeInt(0); // n interfaces, n fields104dout.writeShort(1); // n methods105106// <init> method107dout.writeShort(Modifier.PUBLIC);108dout.writeShort(initNameConst);109dout.writeShort(voidNoArgSigConst);110dout.writeShort(1); // attr count111112// Code attribute113dout.writeShort(codeNameConst);114dout.writeInt(17); // len115dout.writeShort(1); // max stack116dout.writeShort(1); // max locals117dout.writeInt(5); // code len118dout.writeByte(42); // aload_0119dout.writeByte(183); // invokespecial120dout.writeShort(superConstructorMethodRefConst);121dout.writeByte(177); // return122123dout.writeShort(0); // 0 catches124125dout.writeShort(0); // 0 method attrs126127dout.writeShort(0); // 0 class attrs128129dout.close();130byte[] classBytes = bout.toByteArray();131132dout = null;133134return135defineClass(singleClassName, classBytes, 0, classBytes.length);136}137138protected Class findClass(String name) throws ClassNotFoundException {139if (name.equals(singleClassName))140return singleClass;141else142throw new ClassNotFoundException(name);143}144145private int writeUTFConst(String s) throws IOException {146dout.writeByte(1);147dout.writeUTF(s);148return cpoolIndex++;149}150151private int writeClassConst(int nameIndex) throws IOException {152dout.writeByte(7);153dout.writeShort((short) nameIndex);154return cpoolIndex++;155}156157private int writeNameAndTypeConst(int nameIndex, int typeIndex)158throws IOException {159dout.writeByte(12);160dout.writeShort((short) nameIndex);161dout.writeShort((short) typeIndex);162return cpoolIndex++;163}164165private int writeMethodRefConst(int classIndex, int nameAndTypeIndex)166throws IOException {167dout.writeByte(10);168dout.writeShort((short) classIndex);169dout.writeShort((short) nameAndTypeIndex);170return cpoolIndex++;171}172173private final String singleClassName;174private final Class singleClass;175176private DataOutputStream dout;177private int cpoolIndex;178}179180181