8081512: Remove sun.invoke.anon classes, or move / co-locate them with tests
Reviewed-by: mchung, sundar
--- a/jdk/src/java.base/share/classes/sun/invoke/anon/AnonymousClassLoader.java Mon Dec 07 17:04:37 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,234 +0,0 @@
-/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.invoke.anon;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * Anonymous class loader. Will load any valid classfile, producing
- * a {@link Class} metaobject, without installing that class in the
- * system dictionary. Therefore, {@link Class#forName(String)} will never
- * produce a reference to an anonymous class.
- * <p>
- * The access permissions of the anonymous class are borrowed from
- * a <em>host class</em>. The new class behaves as if it were an
- * inner class of the host class. It can access the host's private
- * members, if the creator of the class loader has permission to
- * do so (or to create accessible reflective objects).
- * <p>
- * When the anonymous class is loaded, elements of its constant pool
- * can be patched to new values. This provides a hook to pre-resolve
- * named classes in the constant pool to other classes, including
- * anonymous ones. Also, string constants can be pre-resolved to
- * any reference. (The verifier treats non-string, non-class reference
- * constants as plain objects.)
- * <p>
- * Why include the patching function? It makes some use cases much easier.
- * Second, the constant pool needed some internal patching anyway,
- * to anonymize the loaded class itself. Finally, if you are going
- * to use this seriously, you'll want to build anonymous classes
- * on top of pre-existing anonymous classes, and that requires patching.
- *
- * <p>%%% TO-DO:
- * <ul>
- * <li>needs better documentation</li>
- * <li>needs more security work (for safe delegation)</li>
- * <li>needs a clearer story about error processing</li>
- * <li>patch member references also (use ';' as delimiter char)</li>
- * <li>patch method references to (conforming) method handles</li>
- * </ul>
- *
- * @author jrose
- * @author Remi Forax
- * @see <a href="http://blogs.sun.com/jrose/entry/anonymous_classes_in_the_vm">
- * http://blogs.sun.com/jrose/entry/anonymous_classes_in_the_vm</a>
- */
-
-public class AnonymousClassLoader {
- final Class<?> hostClass;
-
- // Privileged constructor.
- private AnonymousClassLoader(Class<?> hostClass) {
- this.hostClass = hostClass;
- }
-
- public static AnonymousClassLoader make(jdk.internal.misc.Unsafe unsafe, Class<?> hostClass) {
- if (unsafe == null) throw new NullPointerException();
- return new AnonymousClassLoader(hostClass);
- }
-
- public Class<?> loadClass(byte[] classFile) {
- if (defineAnonymousClass == null) {
- // no JVM support; try to fake an approximation
- try {
- return fakeLoadClass(new ConstantPoolParser(classFile).createPatch());
- } catch (InvalidConstantPoolFormatException ee) {
- throw new IllegalArgumentException(ee);
- }
- }
- return loadClass(classFile, null);
- }
-
- public Class<?> loadClass(ConstantPoolPatch classPatch) {
- if (defineAnonymousClass == null) {
- // no JVM support; try to fake an approximation
- return fakeLoadClass(classPatch);
- }
- Object[] patches = classPatch.patchArray;
- // Convert class names (this late in the game)
- // to use slash '/' instead of dot '.'.
- // Java likes dots, but the JVM likes slashes.
- for (int i = 0; i < patches.length; i++) {
- Object value = patches[i];
- if (value != null) {
- byte tag = classPatch.getTag(i);
- switch (tag) {
- case ConstantPoolVisitor.CONSTANT_Class:
- if (value instanceof String) {
- if (patches == classPatch.patchArray)
- patches = patches.clone();
- patches[i] = ((String)value).replace('.', '/');
- }
- break;
- case ConstantPoolVisitor.CONSTANT_Fieldref:
- case ConstantPoolVisitor.CONSTANT_Methodref:
- case ConstantPoolVisitor.CONSTANT_InterfaceMethodref:
- case ConstantPoolVisitor.CONSTANT_NameAndType:
- // When/if the JVM supports these patches,
- // we'll probably need to reformat them also.
- // Meanwhile, let the class loader create the error.
- break;
- }
- }
- }
- return loadClass(classPatch.outer.classFile, classPatch.patchArray);
- }
-
- private Class<?> loadClass(byte[] classFile, Object[] patchArray) {
- try {
- return (Class<?>)
- defineAnonymousClass.invoke(unsafe,
- hostClass, classFile, patchArray);
- } catch (Exception ex) {
- throwReflectedException(ex);
- throw new RuntimeException("error loading into "+hostClass, ex);
- }
- }
-
- private static void throwReflectedException(Exception ex) {
- if (ex instanceof InvocationTargetException) {
- Throwable tex = ((InvocationTargetException)ex).getTargetException();
- if (tex instanceof Error)
- throw (Error) tex;
- ex = (Exception) tex;
- }
- if (ex instanceof RuntimeException) {
- throw (RuntimeException) ex;
- }
- }
-
- private Class<?> fakeLoadClass(ConstantPoolPatch classPatch) {
- // Implementation:
- // 1. Make up a new name nobody has used yet.
- // 2. Inspect the tail-header of the class to find the this_class index.
- // 3. Patch the CONSTANT_Class for this_class to the new name.
- // 4. Add other CP entries required by (e.g.) string patches.
- // 5. Flatten Class constants down to their names, making sure that
- // the host class loader can pick them up again accurately.
- // 6. Generate the edited class file bytes.
- //
- // Potential limitations:
- // * The class won't be truly anonymous, and may interfere with others.
- // * Flattened class constants might not work, because of loader issues.
- // * Pseudo-string constants will not flatten down to real strings.
- // * Method handles will (of course) fail to flatten to linkage strings.
- if (true) throw new UnsupportedOperationException("NYI");
- Object[] cpArray;
- try {
- cpArray = classPatch.getOriginalCP();
- } catch (InvalidConstantPoolFormatException ex) {
- throw new RuntimeException(ex);
- }
- int thisClassIndex = classPatch.getParser().getThisClassIndex();
- String thisClassName = (String) cpArray[thisClassIndex];
- synchronized (AnonymousClassLoader.class) {
- thisClassName = thisClassName+"\\|"+(++fakeNameCounter);
- }
- classPatch.putUTF8(thisClassIndex, thisClassName);
- byte[] classFile = null;
- return unsafe.defineClass(null, classFile, 0, classFile.length,
- hostClass.getClassLoader(),
- hostClass.getProtectionDomain());
- }
- private static int fakeNameCounter = 99999;
-
- // ignore two warnings on this line:
- private static jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
- // preceding line requires that this class be on the boot class path
-
- private static final Method defineAnonymousClass;
- static {
- Method dac = null;
- Class<? extends jdk.internal.misc.Unsafe> unsafeClass = unsafe.getClass();
- try {
- dac = unsafeClass.getMethod("defineAnonymousClass",
- Class.class,
- byte[].class,
- Object[].class);
- } catch (Exception ee) {
- dac = null;
- }
- defineAnonymousClass = dac;
- }
-
- private static void noJVMSupport() {
- throw new UnsupportedOperationException("no JVM support for anonymous classes");
- }
-
-
- private static native Class<?> loadClassInternal(Class<?> hostClass,
- byte[] classFile,
- Object[] patchArray);
-
- public static byte[] readClassFile(Class<?> templateClass) throws IOException {
- String templateName = templateClass.getName();
- int lastDot = templateName.lastIndexOf('.');
- java.net.URL url = templateClass.getResource(templateName.substring(lastDot+1)+".class");
- java.net.URLConnection connection = url.openConnection();
- int contentLength = connection.getContentLength();
- if (contentLength < 0)
- throw new IOException("invalid content length "+contentLength);
-
- byte[] b = connection.getInputStream().readAllBytes();
- if (b.length != contentLength)
- throw new EOFException("Expected:" + contentLength + ", read:" + b.length);
-
- return b;
- }
-}
--- a/jdk/src/java.base/share/classes/sun/invoke/anon/ConstantPoolParser.java Mon Dec 07 17:04:37 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,368 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.invoke.anon;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-
-import static sun.invoke.anon.ConstantPoolVisitor.*;
-
-/** A constant pool parser.
- */
-public class ConstantPoolParser {
- final byte[] classFile;
- final byte[] tags;
- final char[] firstHeader; // maghi, maglo, minor, major, cplen
-
- // these are filled in on first parse:
- int endOffset;
- char[] secondHeader; // flags, this_class, super_class, intlen
-
- // used to decode UTF8 array
- private char[] charArray = new char[80];
-
- /** Creates a constant pool parser.
- * @param classFile an array of bytes containing a class.
- * @throws InvalidConstantPoolFormatException if the header of the class has errors.
- */
- public ConstantPoolParser(byte[] classFile) throws InvalidConstantPoolFormatException {
- this.classFile = classFile;
- this.firstHeader = parseHeader(classFile);
- this.tags = new byte[firstHeader[4]];
- }
-
- /** Create a constant pool parser by loading the bytecodes of the
- * class taken as argument.
- *
- * @param templateClass the class to parse.
- *
- * @throws IOException raised if an I/O occurs when loading
- * the bytecode of the template class.
- * @throws InvalidConstantPoolFormatException if the header of the class has errors.
- *
- * @see #ConstantPoolParser(byte[])
- * @see AnonymousClassLoader#readClassFile(Class)
- */
- public ConstantPoolParser(Class<?> templateClass) throws IOException, InvalidConstantPoolFormatException {
- this(AnonymousClassLoader.readClassFile(templateClass));
- }
-
- /** Creates an empty patch to patch the class file
- * used by the current parser.
- * @return a new class patch.
- */
- public ConstantPoolPatch createPatch() {
- return new ConstantPoolPatch(this);
- }
-
- /** Report the tag of the indicated CP entry.
- * @param index
- * @return one of {@link ConstantPoolVisitor#CONSTANT_Utf8}, etc.
- */
- public byte getTag(int index) {
- getEndOffset(); // trigger an exception if we haven't parsed yet
- return tags[index];
- }
-
- /** Report the length of the constant pool. */
- public int getLength() {
- return firstHeader[4];
- }
-
- /** Report the offset, within the class file, of the start of the constant pool. */
- public int getStartOffset() {
- return firstHeader.length * 2;
- }
-
- /** Report the offset, within the class file, of the end of the constant pool. */
- public int getEndOffset() {
- if (endOffset == 0)
- throw new IllegalStateException("class file has not yet been parsed");
- return endOffset;
- }
-
- /** Report the CP index of this class's own name. */
- public int getThisClassIndex() {
- getEndOffset(); // provoke exception if not yet parsed
- return secondHeader[1];
- }
-
- /** Report the total size of the class file. */
- public int getTailLength() {
- return classFile.length - getEndOffset();
- }
-
- /** Write the head (header plus constant pool)
- * of the class file to the indicated stream.
- */
- public void writeHead(OutputStream out) throws IOException {
- out.write(classFile, 0, getEndOffset());
- }
-
- /** Write the head (header plus constant pool)
- * of the class file to the indicated stream,
- * incorporating the non-null entries of the given array
- * as patches.
- */
- void writePatchedHead(OutputStream out, Object[] patchArray) {
- // this will be useful to partially emulate the class loader on old JVMs
- throw new UnsupportedOperationException("Not yet implemented");
- }
-
- /** Write the tail (everything after the constant pool)
- * of the class file to the indicated stream.
- */
- public void writeTail(OutputStream out) throws IOException {
- out.write(classFile, getEndOffset(), getTailLength());
- }
-
- private static char[] parseHeader(byte[] classFile) throws InvalidConstantPoolFormatException {
- char[] result = new char[5];
- ByteBuffer buffer = ByteBuffer.wrap(classFile);
- for (int i = 0; i < result.length; i++)
- result[i] = (char) getUnsignedShort(buffer);
- int magic = result[0] << 16 | result[1] << 0;
- if (magic != 0xCAFEBABE)
- throw new InvalidConstantPoolFormatException("invalid magic number "+magic);
- // skip major, minor version
- int len = result[4];
- if (len < 1)
- throw new InvalidConstantPoolFormatException("constant pool length < 1");
- return result;
- }
-
- /** Parse the constant pool of the class
- * calling a method visit* each time a constant pool entry is parsed.
- *
- * The order of the calls to visit* is not guaranteed to be the same
- * than the order of the constant pool entry in the bytecode array.
- *
- * @param visitor
- * @throws InvalidConstantPoolFormatException
- */
- public void parse(ConstantPoolVisitor visitor) throws InvalidConstantPoolFormatException {
- ByteBuffer buffer = ByteBuffer.wrap(classFile);
- buffer.position(getStartOffset()); //skip header
-
- Object[] values = new Object[getLength()];
- try {
- parseConstantPool(buffer, values, visitor);
- } catch(BufferUnderflowException e) {
- throw new InvalidConstantPoolFormatException(e);
- }
- if (endOffset == 0) {
- endOffset = buffer.position();
- secondHeader = new char[4];
- for (int i = 0; i < secondHeader.length; i++) {
- secondHeader[i] = (char) getUnsignedShort(buffer);
- }
- }
- resolveConstantPool(values, visitor);
- }
-
- private char[] getCharArray(int utfLength) {
- if (utfLength <= charArray.length)
- return charArray;
- return charArray = new char[utfLength];
- }
-
- private void parseConstantPool(ByteBuffer buffer, Object[] values, ConstantPoolVisitor visitor) throws InvalidConstantPoolFormatException {
- for (int i = 1; i < tags.length; ) {
- byte tag = (byte) getUnsignedByte(buffer);
- assert(tags[i] == 0 || tags[i] == tag);
- tags[i] = tag;
- switch (tag) {
- case CONSTANT_Utf8:
- int utfLen = getUnsignedShort(buffer);
- String value = getUTF8(buffer, utfLen, getCharArray(utfLen));
- visitor.visitUTF8(i, CONSTANT_Utf8, value);
- tags[i] = tag;
- values[i++] = value;
- break;
- case CONSTANT_Integer:
- visitor.visitConstantValue(i, tag, buffer.getInt());
- i++;
- break;
- case CONSTANT_Float:
- visitor.visitConstantValue(i, tag, buffer.getFloat());
- i++;
- break;
- case CONSTANT_Long:
- visitor.visitConstantValue(i, tag, buffer.getLong());
- i+=2;
- break;
- case CONSTANT_Double:
- visitor.visitConstantValue(i, tag, buffer.getDouble());
- i+=2;
- break;
-
- case CONSTANT_Class: // fall through:
- case CONSTANT_String:
- tags[i] = tag;
- values[i++] = new int[] { getUnsignedShort(buffer) };
- break;
-
- case CONSTANT_Fieldref: // fall through:
- case CONSTANT_Methodref: // fall through:
- case CONSTANT_InterfaceMethodref: // fall through:
- case CONSTANT_NameAndType:
- tags[i] = tag;
- values[i++] = new int[] { getUnsignedShort(buffer), getUnsignedShort(buffer) };
- break;
- default:
- throw new AssertionError("invalid constant "+tag);
- }
- }
- }
-
- private void resolveConstantPool(Object[] values, ConstantPoolVisitor visitor) {
- // clean out the int[] values, which are temporary
- for (int beg = 1, end = values.length-1, beg2, end2;
- beg <= end;
- beg = beg2, end = end2) {
- beg2 = end; end2 = beg-1;
- //System.out.println("CP resolve pass: "+beg+".."+end);
- for (int i = beg; i <= end; i++) {
- Object value = values[i];
- if (!(value instanceof int[]))
- continue;
- int[] array = (int[]) value;
- byte tag = tags[i];
- switch (tag) {
- case CONSTANT_String:
- String stringBody = (String) values[array[0]];
- visitor.visitConstantString(i, tag, stringBody, array[0]);
- values[i] = null;
- break;
- case CONSTANT_Class: {
- String className = (String) values[array[0]];
- // use the external form favored by Class.forName:
- className = className.replace('/', '.');
- visitor.visitConstantString(i, tag, className, array[0]);
- values[i] = className;
- break;
- }
- case CONSTANT_NameAndType: {
- String memberName = (String) values[array[0]];
- String signature = (String) values[array[1]];
- visitor.visitDescriptor(i, tag, memberName, signature,
- array[0], array[1]);
- values[i] = new String[] {memberName, signature};
- break;
- }
- case CONSTANT_Fieldref: // fall through:
- case CONSTANT_Methodref: // fall through:
- case CONSTANT_InterfaceMethodref: {
- Object className = values[array[0]];
- Object nameAndType = values[array[1]];
- if (!(className instanceof String) ||
- !(nameAndType instanceof String[])) {
- // one more pass is needed
- if (beg2 > i) beg2 = i;
- if (end2 < i) end2 = i;
- continue;
- }
- String[] nameAndTypeArray = (String[]) nameAndType;
- visitor.visitMemberRef(i, tag,
- (String)className,
- nameAndTypeArray[0],
- nameAndTypeArray[1],
- array[0], array[1]);
- values[i] = null;
- }
- break;
- default:
- continue;
- }
- }
- }
- }
-
- private static int getUnsignedByte(ByteBuffer buffer) {
- return buffer.get() & 0xFF;
- }
-
- private static int getUnsignedShort(ByteBuffer buffer) {
- int b1 = getUnsignedByte(buffer);
- int b2 = getUnsignedByte(buffer);
- return (b1 << 8) + (b2 << 0);
- }
-
- private static String getUTF8(ByteBuffer buffer, int utfLen, char[] charArray) throws InvalidConstantPoolFormatException {
- int utfLimit = buffer.position() + utfLen;
- int index = 0;
- while (buffer.position() < utfLimit) {
- int c = buffer.get() & 0xff;
- if (c > 127) {
- buffer.position(buffer.position() - 1);
- return getUTF8Extended(buffer, utfLimit, charArray, index);
- }
- charArray[index++] = (char)c;
- }
- return new String(charArray, 0, index);
- }
-
- private static String getUTF8Extended(ByteBuffer buffer, int utfLimit, char[] charArray, int index) throws InvalidConstantPoolFormatException {
- int c, c2, c3;
- while (buffer.position() < utfLimit) {
- c = buffer.get() & 0xff;
- switch (c >> 4) {
- case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
- /* 0xxxxxxx*/
- charArray[index++] = (char)c;
- break;
- case 12: case 13:
- /* 110x xxxx 10xx xxxx*/
- c2 = buffer.get();
- if ((c2 & 0xC0) != 0x80)
- throw new InvalidConstantPoolFormatException(
- "malformed input around byte " + buffer.position());
- charArray[index++] = (char)(((c & 0x1F) << 6) |
- (c2 & 0x3F));
- break;
- case 14:
- /* 1110 xxxx 10xx xxxx 10xx xxxx */
- c2 = buffer.get();
- c3 = buffer.get();
- if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80))
- throw new InvalidConstantPoolFormatException(
- "malformed input around byte " + (buffer.position()));
- charArray[index++] = (char)(((c & 0x0F) << 12) |
- ((c2 & 0x3F) << 6) |
- ((c3 & 0x3F) << 0));
- break;
- default:
- /* 10xx xxxx, 1111 xxxx */
- throw new InvalidConstantPoolFormatException(
- "malformed input around byte " + buffer.position());
- }
- }
- // The number of chars produced may be less than utflen
- return new String(charArray, 0, index);
- }
-}
--- a/jdk/src/java.base/share/classes/sun/invoke/anon/ConstantPoolPatch.java Mon Dec 07 17:04:37 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,503 +0,0 @@
-/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.invoke.anon;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Map;
-
-import static sun.invoke.anon.ConstantPoolVisitor.*;
-
-/** A class and its patched constant pool.
- *
- * This class allow to modify (patch) a constant pool
- * by changing the value of its entry.
- * Entry are referenced using index that can be get
- * by parsing the constant pool using
- * {@link ConstantPoolParser#parse(ConstantPoolVisitor)}.
- *
- * @see ConstantPoolVisitor
- * @see ConstantPoolParser#createPatch()
- */
-public class ConstantPoolPatch {
- final ConstantPoolParser outer;
- final Object[] patchArray;
-
- ConstantPoolPatch(ConstantPoolParser outer) {
- this.outer = outer;
- this.patchArray = new Object[outer.getLength()];
- }
-
- /** Create a {@link ConstantPoolParser} and
- * a {@link ConstantPoolPatch} in one step.
- * Equivalent to {@code new ConstantPoolParser(classFile).createPatch()}.
- *
- * @param classFile an array of bytes containing a class.
- * @see #ConstantPoolParser(Class)
- */
- public ConstantPoolPatch(byte[] classFile) throws InvalidConstantPoolFormatException {
- this(new ConstantPoolParser(classFile));
- }
-
- /** Create a {@link ConstantPoolParser} and
- * a {@link ConstantPoolPatch} in one step.
- * Equivalent to {@code new ConstantPoolParser(templateClass).createPatch()}.
- *
- * @param templateClass the class to parse.
- * @see #ConstantPoolParser(Class)
- */
- public ConstantPoolPatch(Class<?> templateClass) throws IOException, InvalidConstantPoolFormatException {
- this(new ConstantPoolParser(templateClass));
- }
-
-
- /** Creates a patch from an existing patch.
- * All changes are copied from that patch.
- * @param patch a patch
- *
- * @see ConstantPoolParser#createPatch()
- */
- public ConstantPoolPatch(ConstantPoolPatch patch) {
- outer = patch.outer;
- patchArray = patch.patchArray.clone();
- }
-
- /** Which parser built this patch? */
- public ConstantPoolParser getParser() {
- return outer;
- }
-
- /** Report the tag at the given index in the constant pool. */
- public byte getTag(int index) {
- return outer.getTag(index);
- }
-
- /** Report the current patch at the given index of the constant pool.
- * Null means no patch will be made.
- * To observe the unpatched entry at the given index, use
- * {@link #getParser()}{@code .}@link ConstantPoolParser#parse(ConstantPoolVisitor)}
- */
- public Object getPatch(int index) {
- Object value = patchArray[index];
- if (value == null) return null;
- switch (getTag(index)) {
- case CONSTANT_Fieldref:
- case CONSTANT_Methodref:
- case CONSTANT_InterfaceMethodref:
- if (value instanceof String)
- value = stripSemis(2, (String) value);
- break;
- case CONSTANT_NameAndType:
- if (value instanceof String)
- value = stripSemis(1, (String) value);
- break;
- }
- return value;
- }
-
- /** Clear all patches. */
- public void clear() {
- Arrays.fill(patchArray, null);
- }
-
- /** Clear one patch. */
- public void clear(int index) {
- patchArray[index] = null;
- }
-
- /** Produce the patches as an array. */
- public Object[] getPatches() {
- return patchArray.clone();
- }
-
- /** Produce the original constant pool as an array. */
- public Object[] getOriginalCP() throws InvalidConstantPoolFormatException {
- return getOriginalCP(0, patchArray.length, -1);
- }
-
- /** Walk the constant pool, applying patches using the given map.
- *
- * @param utf8Map Utf8 strings to modify, if encountered
- * @param classMap Classes (or their names) to modify, if encountered
- * @param valueMap Constant values to modify, if encountered
- * @param deleteUsedEntries if true, delete map entries that are used
- */
- public void putPatches(final Map<String,String> utf8Map,
- final Map<String,Object> classMap,
- final Map<Object,Object> valueMap,
- boolean deleteUsedEntries) throws InvalidConstantPoolFormatException {
- final HashSet<String> usedUtf8Keys;
- final HashSet<String> usedClassKeys;
- final HashSet<Object> usedValueKeys;
- if (deleteUsedEntries) {
- usedUtf8Keys = (utf8Map == null) ? null : new HashSet<String>();
- usedClassKeys = (classMap == null) ? null : new HashSet<String>();
- usedValueKeys = (valueMap == null) ? null : new HashSet<Object>();
- } else {
- usedUtf8Keys = null;
- usedClassKeys = null;
- usedValueKeys = null;
- }
-
- outer.parse(new ConstantPoolVisitor() {
-
- @Override
- public void visitUTF8(int index, byte tag, String utf8) {
- putUTF8(index, utf8Map.get(utf8));
- if (usedUtf8Keys != null) usedUtf8Keys.add(utf8);
- }
-
- @Override
- public void visitConstantValue(int index, byte tag, Object value) {
- putConstantValue(index, tag, valueMap.get(value));
- if (usedValueKeys != null) usedValueKeys.add(value);
- }
-
- @Override
- public void visitConstantString(int index, byte tag, String name, int nameIndex) {
- if (tag == CONSTANT_Class) {
- putConstantValue(index, tag, classMap.get(name));
- if (usedClassKeys != null) usedClassKeys.add(name);
- } else {
- assert(tag == CONSTANT_String);
- visitConstantValue(index, tag, name);
- }
- }
- });
- if (usedUtf8Keys != null) utf8Map.keySet().removeAll(usedUtf8Keys);
- if (usedClassKeys != null) classMap.keySet().removeAll(usedClassKeys);
- if (usedValueKeys != null) valueMap.keySet().removeAll(usedValueKeys);
- }
-
- Object[] getOriginalCP(final int startIndex,
- final int endIndex,
- final int tagMask) throws InvalidConstantPoolFormatException {
- final Object[] cpArray = new Object[endIndex - startIndex];
- outer.parse(new ConstantPoolVisitor() {
-
- void show(int index, byte tag, Object value) {
- if (index < startIndex || index >= endIndex) return;
- if (((1 << tag) & tagMask) == 0) return;
- cpArray[index - startIndex] = value;
- }
-
- @Override
- public void visitUTF8(int index, byte tag, String utf8) {
- show(index, tag, utf8);
- }
-
- @Override
- public void visitConstantValue(int index, byte tag, Object value) {
- assert(tag != CONSTANT_String);
- show(index, tag, value);
- }
-
- @Override
- public void visitConstantString(int index, byte tag,
- String value, int j) {
- show(index, tag, value);
- }
-
- @Override
- public void visitMemberRef(int index, byte tag,
- String className, String memberName,
- String signature,
- int j, int k) {
- show(index, tag, new String[]{ className, memberName, signature });
- }
-
- @Override
- public void visitDescriptor(int index, byte tag,
- String memberName, String signature,
- int j, int k) {
- show(index, tag, new String[]{ memberName, signature });
- }
- });
- return cpArray;
- }
-
- /** Write the head (header plus constant pool)
- * of the patched class file to the indicated stream.
- */
- void writeHead(OutputStream out) throws IOException {
- outer.writePatchedHead(out, patchArray);
- }
-
- /** Write the tail (everything after the constant pool)
- * of the patched class file to the indicated stream.
- */
- void writeTail(OutputStream out) throws IOException {
- outer.writeTail(out);
- }
-
- private void checkConstantTag(byte tag, Object value) {
- if (value == null)
- throw new IllegalArgumentException(
- "invalid null constant value");
- if (classForTag(tag) != value.getClass())
- throw new IllegalArgumentException(
- "invalid constant value"
- + (tag == CONSTANT_None ? ""
- : " for tag "+tagName(tag))
- + " of class "+value.getClass());
- }
-
- private void checkTag(int index, byte putTag) {
- byte tag = outer.tags[index];
- if (tag != putTag)
- throw new IllegalArgumentException(
- "invalid put operation"
- + " for " + tagName(putTag)
- + " at index " + index + " found " + tagName(tag));
- }
-
- private void checkTagMask(int index, int tagBitMask) {
- byte tag = outer.tags[index];
- int tagBit = ((tag & 0x1F) == tag) ? (1 << tag) : 0;
- if ((tagBit & tagBitMask) == 0)
- throw new IllegalArgumentException(
- "invalid put operation"
- + " at index " + index + " found " + tagName(tag));
- }
-
- private static void checkMemberName(String memberName) {
- if (memberName.indexOf(';') >= 0)
- throw new IllegalArgumentException("memberName " + memberName + " contains a ';'");
- }
-
- /** Set the entry of the constant pool indexed by index to
- * a new string.
- *
- * @param index an index to a constant pool entry containing a
- * {@link ConstantPoolVisitor#CONSTANT_Utf8} value.
- * @param utf8 a string
- *
- * @see ConstantPoolVisitor#visitUTF8(int, byte, String)
- */
- public void putUTF8(int index, String utf8) {
- if (utf8 == null) { clear(index); return; }
- checkTag(index, CONSTANT_Utf8);
- patchArray[index] = utf8;
- }
-
- /** Set the entry of the constant pool indexed by index to
- * a new value, depending on its dynamic type.
- *
- * @param index an index to a constant pool entry containing a
- * one of the following structures:
- * {@link ConstantPoolVisitor#CONSTANT_Integer},
- * {@link ConstantPoolVisitor#CONSTANT_Float},
- * {@link ConstantPoolVisitor#CONSTANT_Long},
- * {@link ConstantPoolVisitor#CONSTANT_Double},
- * {@link ConstantPoolVisitor#CONSTANT_String}, or
- * {@link ConstantPoolVisitor#CONSTANT_Class}
- * @param value a boxed int, float, long or double; or a string or class object
- * @throws IllegalArgumentException if the type of the constant does not
- * match the constant pool entry type,
- * as reported by {@link #getTag(int)}
- *
- * @see #putConstantValue(int, byte, Object)
- * @see ConstantPoolVisitor#visitConstantValue(int, byte, Object)
- * @see ConstantPoolVisitor#visitConstantString(int, byte, String, int)
- */
- public void putConstantValue(int index, Object value) {
- if (value == null) { clear(index); return; }
- byte tag = tagForConstant(value.getClass());
- checkConstantTag(tag, value);
- checkTag(index, tag);
- patchArray[index] = value;
- }
-
- /** Set the entry of the constant pool indexed by index to
- * a new value.
- *
- * @param index an index to a constant pool entry matching the given tag
- * @param tag one of the following values:
- * {@link ConstantPoolVisitor#CONSTANT_Integer},
- * {@link ConstantPoolVisitor#CONSTANT_Float},
- * {@link ConstantPoolVisitor#CONSTANT_Long},
- * {@link ConstantPoolVisitor#CONSTANT_Double},
- * {@link ConstantPoolVisitor#CONSTANT_String}, or
- * {@link ConstantPoolVisitor#CONSTANT_Class}
- * @param value a boxed number, string, or class object
- * @throws IllegalArgumentException if the type of the constant does not
- * match the constant pool entry type, or if a class name contains
- * '/' or ';'
- *
- * @see #putConstantValue(int, Object)
- * @see ConstantPoolVisitor#visitConstantValue(int, byte, Object)
- * @see ConstantPoolVisitor#visitConstantString(int, byte, String, int)
- */
- public void putConstantValue(int index, byte tag, Object value) {
- if (value == null) { clear(index); return; }
- checkTag(index, tag);
- if (tag == CONSTANT_Class && value instanceof String) {
- checkClassName((String) value);
- } else if (tag == CONSTANT_String) {
- // the JVM accepts any object as a patch for a string
- } else {
- // make sure the incoming value is the right type
- checkConstantTag(tag, value);
- }
- checkTag(index, tag);
- patchArray[index] = value;
- }
-
- /** Set the entry of the constant pool indexed by index to
- * a new {@link ConstantPoolVisitor#CONSTANT_NameAndType} value.
- *
- * @param index an index to a constant pool entry containing a
- * {@link ConstantPoolVisitor#CONSTANT_NameAndType} value.
- * @param memberName a memberName
- * @param signature a signature
- * @throws IllegalArgumentException if memberName contains the character ';'
- *
- * @see ConstantPoolVisitor#visitDescriptor(int, byte, String, String, int, int)
- */
- public void putDescriptor(int index, String memberName, String signature) {
- checkTag(index, CONSTANT_NameAndType);
- checkMemberName(memberName);
- patchArray[index] = addSemis(memberName, signature);
- }
-
- /** Set the entry of the constant pool indexed by index to
- * a new {@link ConstantPoolVisitor#CONSTANT_Fieldref},
- * {@link ConstantPoolVisitor#CONSTANT_Methodref}, or
- * {@link ConstantPoolVisitor#CONSTANT_InterfaceMethodref} value.
- *
- * @param index an index to a constant pool entry containing a member reference
- * @param className a class name
- * @param memberName a field or method name
- * @param signature a field or method signature
- * @throws IllegalArgumentException if memberName contains the character ';'
- * or signature is not a correct signature
- *
- * @see ConstantPoolVisitor#visitMemberRef(int, byte, String, String, String, int, int)
- */
- public void putMemberRef(int index, byte tag,
- String className, String memberName, String signature) {
- checkTagMask(tag, CONSTANT_MemberRef_MASK);
- checkTag(index, tag);
- checkClassName(className);
- checkMemberName(memberName);
- if (signature.startsWith("(") == (tag == CONSTANT_Fieldref))
- throw new IllegalArgumentException("bad signature: "+signature);
- patchArray[index] = addSemis(className, memberName, signature);
- }
-
- private static final int CONSTANT_MemberRef_MASK =
- CONSTANT_Fieldref
- | CONSTANT_Methodref
- | CONSTANT_InterfaceMethodref;
-
- private static final Map<Class<?>, Byte> CONSTANT_VALUE_CLASS_TAG
- = new IdentityHashMap<Class<?>, Byte>(6);
- private static final Class<?>[] CONSTANT_VALUE_CLASS = new Class<?>[16];
- static {
- Object[][] values = {
- {Integer.class, CONSTANT_Integer},
- {Long.class, CONSTANT_Long},
- {Float.class, CONSTANT_Float},
- {Double.class, CONSTANT_Double},
- {String.class, CONSTANT_String},
- {Class.class, CONSTANT_Class}
- };
- for (Object[] value : values) {
- Class<?> cls = (Class<?>)value[0];
- Byte tag = (Byte) value[1];
- CONSTANT_VALUE_CLASS_TAG.put(cls, tag);
- CONSTANT_VALUE_CLASS[(byte)tag] = cls;
- }
- }
-
- static Class<?> classForTag(byte tag) {
- if ((tag & 0xFF) >= CONSTANT_VALUE_CLASS.length)
- return null;
- return CONSTANT_VALUE_CLASS[tag];
- }
-
- static byte tagForConstant(Class<?> cls) {
- Byte tag = CONSTANT_VALUE_CLASS_TAG.get(cls);
- return (tag == null) ? CONSTANT_None : (byte)tag;
- }
-
- private static void checkClassName(String className) {
- if (className.indexOf('/') >= 0 || className.indexOf(';') >= 0)
- throw new IllegalArgumentException("invalid class name " + className);
- }
-
- static String addSemis(String name, String... names) {
- StringBuilder buf = new StringBuilder(name.length() * 5);
- buf.append(name);
- for (String name2 : names) {
- buf.append(';').append(name2);
- }
- String res = buf.toString();
- assert(stripSemis(names.length, res)[0].equals(name));
- assert(stripSemis(names.length, res)[1].equals(names[0]));
- assert(names.length == 1 ||
- stripSemis(names.length, res)[2].equals(names[1]));
- return res;
- }
-
- static String[] stripSemis(int count, String string) {
- String[] res = new String[count+1];
- int pos = 0;
- for (int i = 0; i < count; i++) {
- int pos2 = string.indexOf(';', pos);
- if (pos2 < 0) pos2 = string.length(); // yuck
- res[i] = string.substring(pos, pos2);
- pos = pos2;
- }
- res[count] = string.substring(pos);
- return res;
- }
-
- public String toString() {
- StringBuilder buf = new StringBuilder(this.getClass().getName());
- buf.append("{");
- Object[] origCP = null;
- for (int i = 0; i < patchArray.length; i++) {
- if (patchArray[i] == null) continue;
- if (origCP != null) {
- buf.append(", ");
- } else {
- try {
- origCP = getOriginalCP();
- } catch (InvalidConstantPoolFormatException ee) {
- origCP = new Object[0];
- }
- }
- Object orig = (i < origCP.length) ? origCP[i] : "?";
- buf.append(orig).append("=").append(patchArray[i]);
- }
- buf.append("}");
- return buf.toString();
- }
-}
--- a/jdk/src/java.base/share/classes/sun/invoke/anon/ConstantPoolVisitor.java Mon Dec 07 17:04:37 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.invoke.anon;
-
-/**
- * A visitor called by {@link ConstantPoolParser#parse(ConstantPoolVisitor)}
- * when a constant pool entry is parsed.
- * <p>
- * A visit* method is called when a constant pool entry is parsed.
- * The first argument is always the constant pool index.
- * The second argument is always the constant pool tag,
- * even for methods like {@link #visitUTF8(int, byte, String)} which only apply to one tag.
- * String arguments refer to Utf8 or NameAndType entries declared elsewhere,
- * and are always accompanied by the indexes of those entries.
- * <p>
- * The order of the calls to the visit* methods is not necessarily related
- * to the order of the entries in the constant pool.
- * If one entry has a reference to another entry, the latter (lower-level)
- * entry will be visited first.
- * <p>
- * The following table shows the relation between constant pool entry
- * types and the corresponding visit* methods:
- *
- * <table border=1 cellpadding=5 summary="constant pool visitor methods">
- * <tr><th>Tag(s)</th><th>Method</th></tr>
- * <tr>
- * <td>{@link #CONSTANT_Utf8}</td>
- * <td>{@link #visitUTF8(int, byte, String)}</td>
- * </tr><tr>
- * <td>{@link #CONSTANT_Integer}, {@link #CONSTANT_Float},
- * {@link #CONSTANT_Long}, {@link #CONSTANT_Double}</td>
- * <td>{@link #visitConstantValue(int, byte, Object)}</td>
- * </tr><tr>
- * <td>{@link #CONSTANT_String}, {@link #CONSTANT_Class}</td>
- * <td>{@link #visitConstantString(int, byte, String, int)}</td>
- * </tr><tr>
- * <td>{@link #CONSTANT_NameAndType}</td>
- * <td>{@link #visitDescriptor(int, byte, String, String, int, int)}</td>
- * </tr><tr>
- * <td>{@link #CONSTANT_Fieldref},
- * {@link #CONSTANT_Methodref},
- * {@link #CONSTANT_InterfaceMethodref}</td>
- * <td>{@link #visitMemberRef(int, byte, String, String, String, int, int)}</td>
- * </tr>
- * </table>
- *
- * @see ConstantPoolPatch
- * @author Remi Forax
- * @author jrose
- */
-public class ConstantPoolVisitor {
- /** Called each time an UTF8 constant pool entry is found.
- * @param index the constant pool index
- * @param tag always {@link #CONSTANT_Utf8}
- * @param utf8 string encoded in modified UTF-8 format passed as a {@code String}
- *
- * @see ConstantPoolPatch#putUTF8(int, String)
- */
- public void visitUTF8(int index, byte tag, String utf8) {
- // do nothing
- }
-
- /** Called for each constant pool entry that encodes an integer,
- * a float, a long, or a double.
- * Constant strings and classes are not managed by this method but
- * by {@link #visitConstantString(int, byte, String, int)}.
- *
- * @param index the constant pool index
- * @param tag one of {@link #CONSTANT_Integer},
- * {@link #CONSTANT_Float},
- * {@link #CONSTANT_Long},
- * or {@link #CONSTANT_Double}
- * @param value encoded value
- *
- * @see ConstantPoolPatch#putConstantValue(int, Object)
- */
- public void visitConstantValue(int index, byte tag, Object value) {
- // do nothing
- }
-
- /** Called for each constant pool entry that encodes a string or a class.
- * @param index the constant pool index
- * @param tag one of {@link #CONSTANT_String},
- * {@link #CONSTANT_Class},
- * @param name string body or class name (using dot separator)
- * @param nameIndex the index of the Utf8 string for the name
- *
- * @see ConstantPoolPatch#putConstantValue(int, byte, Object)
- */
- public void visitConstantString(int index, byte tag,
- String name, int nameIndex) {
- // do nothing
- }
-
- /** Called for each constant pool entry that encodes a name and type.
- * @param index the constant pool index
- * @param tag always {@link #CONSTANT_NameAndType}
- * @param memberName a field or method name
- * @param signature the member signature
- * @param memberNameIndex index of the Utf8 string for the member name
- * @param signatureIndex index of the Utf8 string for the signature
- *
- * @see ConstantPoolPatch#putDescriptor(int, String, String)
- */
- public void visitDescriptor(int index, byte tag,
- String memberName, String signature,
- int memberNameIndex, int signatureIndex) {
- // do nothing
- }
-
- /** Called for each constant pool entry that encodes a field or method.
- * @param index the constant pool index
- * @param tag one of {@link #CONSTANT_Fieldref},
- * or {@link #CONSTANT_Methodref},
- * or {@link #CONSTANT_InterfaceMethodref}
- * @param className the class name (using dot separator)
- * @param memberName name of the field or method
- * @param signature the field or method signature
- * @param classNameIndex index of the Utf8 string for the class name
- * @param descriptorIndex index of the NameAndType descriptor constant
- *
- * @see ConstantPoolPatch#putMemberRef(int, byte, String, String, String)
- */
- public void visitMemberRef(int index, byte tag,
- String className, String memberName, String signature,
- int classNameIndex, int descriptorIndex) {
- // do nothing
- }
-
- public static final byte
- CONSTANT_None = 0,
- CONSTANT_Utf8 = 1,
- //CONSTANT_Unicode = 2, /* unused */
- CONSTANT_Integer = 3,
- CONSTANT_Float = 4,
- CONSTANT_Long = 5,
- CONSTANT_Double = 6,
- CONSTANT_Class = 7,
- CONSTANT_String = 8,
- CONSTANT_Fieldref = 9,
- CONSTANT_Methodref = 10,
- CONSTANT_InterfaceMethodref = 11,
- CONSTANT_NameAndType = 12;
-
- private static String[] TAG_NAMES = {
- "Empty",
- "Utf8",
- null, //"Unicode",
- "Integer",
- "Float",
- "Long",
- "Double",
- "Class",
- "String",
- "Fieldref",
- "Methodref",
- "InterfaceMethodref",
- "NameAndType"
- };
-
- public static String tagName(byte tag) {
- String name = null;
- if ((tag & 0xFF) < TAG_NAMES.length)
- name = TAG_NAMES[tag];
- if (name == null)
- name = "Unknown#"+(tag&0xFF);
- return name;
- }
-}
--- a/jdk/src/java.base/share/classes/sun/invoke/anon/InvalidConstantPoolFormatException.java Mon Dec 07 17:04:37 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.invoke.anon;
-
-/** Exception used when there is an error in the constant pool
- * format.
- */
-public class InvalidConstantPoolFormatException extends Exception {
- private static final long serialVersionUID=-6103888330523770949L;
-
- public InvalidConstantPoolFormatException(String message,Throwable cause) {
- super(message,cause);
- }
-
- public InvalidConstantPoolFormatException(String message) {
- super(message);
- }
-
- public InvalidConstantPoolFormatException(Throwable cause) {
- super(cause);
- }
-}
--- a/jdk/test/sun/invoke/anon/ConstantPoolPatch/OptimalMapSize.java Mon Dec 07 17:04:37 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
- * @bug 8080535
- * @summary Static storages should be initialized with optimal capacity
- * @library /lib/testlibrary
- * @build jdk.testlibrary.OptimalCapacity
- * @run main OptimalMapSize
- */
-
-import jdk.testlibrary.OptimalCapacity;
-
-public class OptimalMapSize {
- public static void main(String[] args) throws Throwable {
- OptimalCapacity.ofIdentityHashMap(
- Class.forName("sun.invoke.anon.ConstantPoolPatch"),
- "CONSTANT_VALUE_CLASS_TAG", 6);
- }
-}