diff --git a/openjdk8/src/main/docker/ConstantPool.java b/openjdk8/src/main/docker/ConstantPool.java
new file mode 100644
index 00000000..c8ea26d2
--- /dev/null
+++ b/openjdk8/src/main/docker/ConstantPool.java
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.sun.org.apache.bcel.internal.classfile;
+
+
+import com.sun.org.apache.bcel.internal.Constants;
+import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
+import java.io.*;
+
+/**
+ * This class represents the constant pool, i.e., a table of constants, of
+ * a parsed classfile. It may contain null references, due to the JVM
+ * specification that skips an entry after an 8-byte constant (double,
+ * long) entry. Those interested in generating constant pools
+ * programatically should see
+ * ConstantPoolGen.
+
+ * @see Constant
+ * @see com.sun.org.apache.bcel.internal.generic.ConstantPoolGen
+ * @author M. Dahm
+ * @LastModified: May 2022
+ */
+public class ConstantPool implements Cloneable, Node, Serializable {
+ private int constant_pool_count;
+ private Constant[] constant_pool;
+
+ /**
+ * @param constant_pool Array of constants
+ */
+ public ConstantPool(Constant[] constant_pool)
+ {
+ setConstantPool(constant_pool);
+ }
+
+ /**
+ * Read constants from given file stream.
+ *
+ * @param file Input stream
+ * @throws IOException
+ * @throws ClassFormatException
+ */
+ ConstantPool(DataInputStream file) throws IOException, ClassFormatException
+ {
+ byte tag;
+
+ constant_pool_count = file.readUnsignedShort();
+ constant_pool = new Constant[constant_pool_count];
+
+ /* constant_pool[0] is unused by the compiler and may be used freely
+ * by the implementation.
+ */
+ for(int i=1; i < constant_pool_count; i++) {
+ constant_pool[i] = Constant.readConstant(file);
+
+ /* Quote from the JVM specification:
+ * "All eight byte constants take up two spots in the constant pool.
+ * If this is the n'th byte in the constant pool, then the next item
+ * will be numbered n+2"
+ *
+ * Thus we have to increment the index counter.
+ */
+ tag = constant_pool[i].getTag();
+ if((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long))
+ i++;
+ }
+ }
+
+ /**
+ * Called by objects that are traversing the nodes of the tree implicitely
+ * defined by the contents of a Java class. I.e., the hierarchy of methods,
+ * fields, attributes, etc. spawns a tree of objects.
+ *
+ * @param v Visitor object
+ */
+ public void accept(Visitor v) {
+ v.visitConstantPool(this);
+ }
+
+ /**
+ * Resolve constant to a string representation.
+ *
+ * @param constant Constant to be printed
+ * @return String representation
+ */
+ public String constantToString(Constant c)
+ throws ClassFormatException
+ {
+ String str;
+ int i;
+ byte tag = c.getTag();
+
+ switch(tag) {
+ case Constants.CONSTANT_Class:
+ i = ((ConstantClass)c).getNameIndex();
+ c = getConstant(i, Constants.CONSTANT_Utf8);
+ str = Utility.compactClassName(((ConstantUtf8)c).getBytes(), false);
+ break;
+
+ case Constants.CONSTANT_String:
+ i = ((ConstantString)c).getStringIndex();
+ c = getConstant(i, Constants.CONSTANT_Utf8);
+ str = "\"" + escape(((ConstantUtf8)c).getBytes()) + "\"";
+ break;
+
+ case Constants.CONSTANT_Utf8: str = ((ConstantUtf8)c).getBytes(); break;
+ case Constants.CONSTANT_Double: str = "" + ((ConstantDouble)c).getBytes(); break;
+ case Constants.CONSTANT_Float: str = "" + ((ConstantFloat)c).getBytes(); break;
+ case Constants.CONSTANT_Long: str = "" + ((ConstantLong)c).getBytes(); break;
+ case Constants.CONSTANT_Integer: str = "" + ((ConstantInteger)c).getBytes(); break;
+
+ case Constants.CONSTANT_NameAndType:
+ str = (constantToString(((ConstantNameAndType)c).getNameIndex(),
+ Constants.CONSTANT_Utf8) + " " +
+ constantToString(((ConstantNameAndType)c).getSignatureIndex(),
+ Constants.CONSTANT_Utf8));
+ break;
+
+ case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref:
+ case Constants.CONSTANT_Fieldref:
+ str = (constantToString(((ConstantCP)c).getClassIndex(),
+ Constants.CONSTANT_Class) + "." +
+ constantToString(((ConstantCP)c).getNameAndTypeIndex(),
+ Constants.CONSTANT_NameAndType));
+ break;
+
+ default: // Never reached
+ throw new RuntimeException("Unknown constant type " + tag);
+ }
+
+ return str;
+ }
+
+ private static final String escape(String str) {
+ int len = str.length();
+ StringBuffer buf = new StringBuffer(len + 5);
+ char[] ch = str.toCharArray();
+
+ for(int i=0; i < len; i++) {
+ switch(ch[i]) {
+ case '\n' : buf.append("\\n"); break;
+ case '\r' : buf.append("\\r"); break;
+ case '\t' : buf.append("\\t"); break;
+ case '\b' : buf.append("\\b"); break;
+ case '"' : buf.append("\\\""); break;
+ default: buf.append(ch[i]);
+ }
+ }
+
+ return buf.toString();
+ }
+
+
+ /**
+ * Retrieve constant at `index' from constant pool and resolve it to
+ * a string representation.
+ *
+ * @param index of constant in constant pool
+ * @param tag expected type
+ * @return String representation
+ */
+ public String constantToString(int index, byte tag)
+ throws ClassFormatException
+ {
+ Constant c = getConstant(index, tag);
+ return constantToString(c);
+ }
+
+ /**
+ * Dump constant pool to file stream in binary format.
+ *
+ * @param file Output file stream
+ * @throws IOException
+ */
+ public void dump(DataOutputStream file) throws IOException
+ {
+ /*
+ * Constants over the size of the constant pool shall not be written out.
+ * This is a redundant measure as the ConstantPoolGen should have already
+ * reported an error back in the situation.
+ */
+ int size = constant_pool_count < ConstantPoolGen.CONSTANT_POOL_SIZE - 1 ?
+ constant_pool_count : ConstantPoolGen.CONSTANT_POOL_SIZE - 1;
+
+ file.writeShort(size);
+ for(int i=1; i < size; i++)
+ if(constant_pool[i] != null)
+ constant_pool[i].dump(file);
+ }
+
+ /**
+ * Get constant from constant pool.
+ *
+ * @param index Index in constant pool
+ * @return Constant value
+ * @see Constant
+ */
+ public Constant getConstant(int index) {
+ if (index >= constant_pool.length || index < 0)
+ throw new ClassFormatException("Invalid constant pool reference: " +
+ index + ". Constant pool size is: " +
+ constant_pool.length);
+ return constant_pool[index];
+ }
+
+ /**
+ * Get constant from constant pool and check whether it has the
+ * expected type.
+ *
+ * @param index Index in constant pool
+ * @param tag Tag of expected constant, i.e., its type
+ * @return Constant value
+ * @see Constant
+ * @throws ClassFormatException
+ */
+ public Constant getConstant(int index, byte tag)
+ throws ClassFormatException
+ {
+ Constant c;
+
+ c = getConstant(index);
+
+ if(c == null)
+ throw new ClassFormatException("Constant pool at index " + index + " is null.");
+
+ if(c.getTag() == tag)
+ return c;
+ else
+ throw new ClassFormatException("Expected class `" + Constants.CONSTANT_NAMES[tag] +
+ "' at index " + index + " and got " + c);
+ }
+
+ /**
+ * @return Array of constants.
+ * @see Constant
+ */
+ public Constant[] getConstantPool() { return constant_pool; }
+ /**
+ * Get string from constant pool and bypass the indirection of
+ * `ConstantClass' and `ConstantString' objects. I.e. these classes have
+ * an index field that points to another entry of the constant pool of
+ * type `ConstantUtf8' which contains the real data.
+ *
+ * @param index Index in constant pool
+ * @param tag Tag of expected constant, either ConstantClass or ConstantString
+ * @return Contents of string reference
+ * @see ConstantClass
+ * @see ConstantString
+ * @throws ClassFormatException
+ */
+ public String getConstantString(int index, byte tag)
+ throws ClassFormatException
+ {
+ Constant c;
+ int i;
+
+ c = getConstant(index, tag);
+
+ /* This switch() is not that elegant, since the two classes have the
+ * same contents, they just differ in the name of the index
+ * field variable.
+ * But we want to stick to the JVM naming conventions closely though
+ * we could have solved these more elegantly by using the same
+ * variable name or by subclassing.
+ */
+ switch(tag) {
+ case Constants.CONSTANT_Class: i = ((ConstantClass)c).getNameIndex(); break;
+ case Constants.CONSTANT_String: i = ((ConstantString)c).getStringIndex(); break;
+ default:
+ throw new RuntimeException("getConstantString called with illegal tag " + tag);
+ }
+
+ // Finally get the string from the constant pool
+ c = getConstant(i, Constants.CONSTANT_Utf8);
+ return ((ConstantUtf8)c).getBytes();
+ }
+ /**
+ * @return Length of constant pool.
+ */
+ public int getLength()
+ {
+ return constant_pool_count;
+ }
+
+ /**
+ * @param constant Constant to set
+ */
+ public void setConstant(int index, Constant constant) {
+ constant_pool[index] = constant;
+ }
+
+ /**
+ * @param constant_pool
+ */
+ public void setConstantPool(Constant[] constant_pool) {
+ this.constant_pool = constant_pool;
+ constant_pool_count = (constant_pool == null)? 0 : constant_pool.length;
+ }
+ /**
+ * @return String representation.
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ for(int i=1; i < constant_pool_count; i++)
+ buf.append(i + ")" + constant_pool[i] + "\n");
+
+ return buf.toString();
+ }
+
+ /**
+ * @return deep copy of this constant pool
+ */
+ public ConstantPool copy() {
+ ConstantPool c = null;
+
+ try {
+ c = (ConstantPool)clone();
+ } catch(CloneNotSupportedException e) {}
+
+ c.constant_pool = new Constant[constant_pool_count];
+
+ for(int i=1; i < constant_pool_count; i++) {
+ if(constant_pool[i] != null)
+ c.constant_pool[i] = constant_pool[i].copy();
+ }
+
+ return c;
+ }
+}
diff --git a/openjdk8/src/main/docker/ConstantPoolGen.java b/openjdk8/src/main/docker/ConstantPoolGen.java
new file mode 100644
index 00000000..bdd25a64
--- /dev/null
+++ b/openjdk8/src/main/docker/ConstantPoolGen.java
@@ -0,0 +1,763 @@
+/*
+ * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ */
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.sun.org.apache.bcel.internal.generic;
+
+
+import com.sun.org.apache.bcel.internal.Constants;
+import com.sun.org.apache.bcel.internal.classfile.*;
+import java.util.HashMap;
+
+/**
+ * This class is used to build up a constant pool. The user adds
+ * constants via `addXXX' methods, `addString', `addClass',
+ * etc.. These methods return an index into the constant
+ * pool. Finally, `getFinalConstantPool()' returns the constant pool
+ * built up. Intermediate versions of the constant pool can be
+ * obtained with `getConstantPool()'. A constant pool has capacity for
+ * Constants.MAX_SHORT entries. Note that the first (0) is used by the
+ * JVM and that Double and Long constants need two slots.
+ *
+ * @author M. Dahm
+ * @see Constant
+ * @LastModified: May 2022
+ */
+public class ConstantPoolGen implements java.io.Serializable {
+ public static final int CONSTANT_POOL_SIZE = 65536;
+ protected int size = 1024; // Inital size, sufficient in most cases
+ protected Constant[] constants = new Constant[size];
+ protected int index = 1; // First entry (0) used by JVM
+
+ private static final String METHODREF_DELIM = ":";
+ private static final String IMETHODREF_DELIM = "#";
+ private static final String FIELDREF_DELIM = "&";
+ private static final String NAT_DELIM = "%";
+
+ private static class Index implements java.io.Serializable {
+ int index;
+ Index(int i) { index = i; }
+ }
+
+ /**
+ * Initialize with given array of constants.
+ *
+ * @param c array of given constants, new ones will be appended
+ */
+ public ConstantPoolGen(Constant[] cs) {
+ if(cs.length > size) {
+ size = Math.min(cs.length, CONSTANT_POOL_SIZE);
+ constants = new Constant[size];
+ }
+
+ System.arraycopy(cs, 0, constants, 0, cs.length);
+
+ if(cs.length > 0)
+ index = cs.length;
+
+ for(int i=1; i < index; i++) {
+ Constant c = constants[i];
+
+ if(c instanceof ConstantString) {
+ ConstantString s = (ConstantString)c;
+ ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()];
+
+ string_table.put(u8.getBytes(), new Index(i));
+ } else if(c instanceof ConstantClass) {
+ ConstantClass s = (ConstantClass)c;
+ ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()];
+
+ class_table.put(u8.getBytes(), new Index(i));
+ } else if(c instanceof ConstantNameAndType) {
+ ConstantNameAndType n = (ConstantNameAndType)c;
+ ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()];
+ ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()];
+
+ n_a_t_table.put(u8.getBytes() + NAT_DELIM + u8_2.getBytes(), new Index(i));
+ } else if(c instanceof ConstantUtf8) {
+ ConstantUtf8 u = (ConstantUtf8)c;
+
+ utf8_table.put(u.getBytes(), new Index(i));
+ } else if(c instanceof ConstantCP) {
+ ConstantCP m = (ConstantCP)c;
+ ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()];
+ ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()];
+
+ ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()];
+ String class_name = u8.getBytes().replace('/', '.');
+
+ u8 = (ConstantUtf8)constants[n.getNameIndex()];
+ String method_name = u8.getBytes();
+
+ u8 = (ConstantUtf8)constants[n.getSignatureIndex()];
+ String signature = u8.getBytes();
+
+ String delim = METHODREF_DELIM;
+
+ if(c instanceof ConstantInterfaceMethodref)
+ delim = IMETHODREF_DELIM;
+ else if(c instanceof ConstantFieldref)
+ delim = FIELDREF_DELIM;
+
+ cp_table.put(class_name + delim + method_name + delim + signature, new Index(i));
+ }
+ }
+ }
+
+ /**
+ * Initialize with given constant pool.
+ */
+ public ConstantPoolGen(ConstantPool cp) {
+ this(cp.getConstantPool());
+ }
+
+ /**
+ * Create empty constant pool.
+ */
+ public ConstantPoolGen() {}
+
+ /** Resize internal array of constants.
+ */
+ protected void adjustSize() {
+ // 3 extra spaces are needed as some entries may take 3 slots
+ if (index + 3 >= CONSTANT_POOL_SIZE) {
+ throw new RuntimeException("The number of constants " + (index + 3) +
+ " is over the size of the constant pool: " +
+ (CONSTANT_POOL_SIZE - 1));
+ }
+
+ if(index + 3 >= size) {
+ Constant[] cs = constants;
+
+ size *= 2;
+ // the constant array shall not exceed the size of the constant pool
+ size = Math.min(size, CONSTANT_POOL_SIZE);
+ constants = new Constant[size];
+ System.arraycopy(cs, 0, constants, 0, index);
+ }
+ }
+
+ private HashMap string_table = new HashMap();
+
+ /**
+ * Look for ConstantString in ConstantPool containing String `str'.
+ *
+ * @param str String to search for
+ * @return index on success, -1 otherwise
+ */
+ public int lookupString(String str) {
+ Index index = (Index)string_table.get(str);
+ return (index != null)? index.index : -1;
+ }
+
+ /**
+ * Add a new String constant to the ConstantPool, if it is not already in there.
+ *
+ * @param str String to add
+ * @return index of entry
+ */
+ public int addString(String str) {
+ int ret;
+
+ if((ret = lookupString(str)) != -1)
+ return ret; // Already in CP
+
+ int utf8 = addUtf8(str);
+
+ adjustSize();
+
+ ConstantString s = new ConstantString(utf8);
+
+ ret = index;
+ constants[index++] = s;
+
+ string_table.put(str, new Index(ret));
+
+ return ret;
+ }
+
+ private HashMap class_table = new HashMap();
+
+ /**
+ * Look for ConstantClass in ConstantPool named `str'.
+ *
+ * @param str String to search for
+ * @return index on success, -1 otherwise
+ */
+ public int lookupClass(String str) {
+ Index index = (Index)class_table.get(str.replace('.', '/'));
+ return (index != null)? index.index : -1;
+ }
+
+ private int addClass_(String clazz) {
+ int ret;
+
+ if((ret = lookupClass(clazz)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ ConstantClass c = new ConstantClass(addUtf8(clazz));
+
+ ret = index;
+ constants[index++] = c;
+
+ class_table.put(clazz, new Index(ret));
+
+ return ret;
+ }
+
+ /**
+ * Add a new Class reference to the ConstantPool, if it is not already in there.
+ *
+ * @param str Class to add
+ * @return index of entry
+ */
+ public int addClass(String str) {
+ return addClass_(str.replace('.', '/'));
+ }
+
+ /**
+ * Add a new Class reference to the ConstantPool for a given type.
+ *
+ * @param str Class to add
+ * @return index of entry
+ */
+ public int addClass(ObjectType type) {
+ return addClass(type.getClassName());
+ }
+
+ /**
+ * Add a reference to an array class (e.g. String[][]) as needed by MULTIANEWARRAY
+ * instruction, e.g. to the ConstantPool.
+ *
+ * @param type type of array class
+ * @return index of entry
+ */
+ public int addArrayClass(ArrayType type) {
+ return addClass_(type.getSignature());
+ }
+
+ /**
+ * Look for ConstantInteger in ConstantPool.
+ *
+ * @param n integer number to look for
+ * @return index on success, -1 otherwise
+ */
+ public int lookupInteger(int n) {
+ for(int i=1; i < index; i++) {
+ if(constants[i] instanceof ConstantInteger) {
+ ConstantInteger c = (ConstantInteger)constants[i];
+
+ if(c.getBytes() == n)
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Add a new Integer constant to the ConstantPool, if it is not already in there.
+ *
+ * @param n integer number to add
+ * @return index of entry
+ */
+ public int addInteger(int n) {
+ int ret;
+
+ if((ret = lookupInteger(n)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ ret = index;
+ constants[index++] = new ConstantInteger(n);
+
+ return ret;
+ }
+
+ /**
+ * Look for ConstantFloat in ConstantPool.
+ *
+ * @param n Float number to look for
+ * @return index on success, -1 otherwise
+ */
+ public int lookupFloat(float n) {
+ int bits = Float.floatToIntBits(n);
+
+ for(int i=1; i < index; i++) {
+ if(constants[i] instanceof ConstantFloat) {
+ ConstantFloat c = (ConstantFloat)constants[i];
+
+ if(Float.floatToIntBits(c.getBytes()) == bits)
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Add a new Float constant to the ConstantPool, if it is not already in there.
+ *
+ * @param n Float number to add
+ * @return index of entry
+ */
+ public int addFloat(float n) {
+ int ret;
+
+ if((ret = lookupFloat(n)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ ret = index;
+ constants[index++] = new ConstantFloat(n);
+
+ return ret;
+ }
+
+ private HashMap utf8_table = new HashMap();
+
+ /**
+ * Look for ConstantUtf8 in ConstantPool.
+ *
+ * @param n Utf8 string to look for
+ * @return index on success, -1 otherwise
+ */
+ public int lookupUtf8(String n) {
+ Index index = (Index)utf8_table.get(n);
+
+ return (index != null)? index.index : -1;
+ }
+
+ /**
+ * Add a new Utf8 constant to the ConstantPool, if it is not already in there.
+ *
+ * @param n Utf8 string to add
+ * @return index of entry
+ */
+ public int addUtf8(String n) {
+ int ret;
+
+ if((ret = lookupUtf8(n)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ ret = index;
+ constants[index++] = new ConstantUtf8(n);
+
+ utf8_table.put(n, new Index(ret));
+
+ return ret;
+ }
+
+ /**
+ * Look for ConstantLong in ConstantPool.
+ *
+ * @param n Long number to look for
+ * @return index on success, -1 otherwise
+ */
+ public int lookupLong(long n) {
+ for(int i=1; i < index; i++) {
+ if(constants[i] instanceof ConstantLong) {
+ ConstantLong c = (ConstantLong)constants[i];
+
+ if(c.getBytes() == n)
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Add a new long constant to the ConstantPool, if it is not already in there.
+ *
+ * @param n Long number to add
+ * @return index of entry
+ */
+ public int addLong(long n) {
+ int ret;
+
+ if((ret = lookupLong(n)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ ret = index;
+ constants[index] = new ConstantLong(n);
+ index += 2; // Wastes one entry according to spec
+
+ return ret;
+ }
+
+ /**
+ * Look for ConstantDouble in ConstantPool.
+ *
+ * @param n Double number to look for
+ * @return index on success, -1 otherwise
+ */
+ public int lookupDouble(double n) {
+ long bits = Double.doubleToLongBits(n);
+
+ for(int i=1; i < index; i++) {
+ if(constants[i] instanceof ConstantDouble) {
+ ConstantDouble c = (ConstantDouble)constants[i];
+
+ if(Double.doubleToLongBits(c.getBytes()) == bits)
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * Add a new double constant to the ConstantPool, if it is not already in there.
+ *
+ * @param n Double number to add
+ * @return index of entry
+ */
+ public int addDouble(double n) {
+ int ret;
+
+ if((ret = lookupDouble(n)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ ret = index;
+ constants[index] = new ConstantDouble(n);
+ index += 2; // Wastes one entry according to spec
+
+ return ret;
+ }
+
+ private HashMap n_a_t_table = new HashMap();
+
+ /**
+ * Look for ConstantNameAndType in ConstantPool.
+ *
+ * @param name of variable/method
+ * @param signature of variable/method
+ * @return index on success, -1 otherwise
+ */
+ public int lookupNameAndType(String name, String signature) {
+ Index index = (Index)n_a_t_table.get(name + NAT_DELIM + signature);
+ return (index != null)? index.index : -1;
+ }
+
+ /**
+ * Add a new NameAndType constant to the ConstantPool if it is not already
+ * in there.
+ *
+ * @param n NameAndType string to add
+ * @return index of entry
+ */
+ public int addNameAndType(String name, String signature) {
+ int ret;
+ int name_index, signature_index;
+
+ if((ret = lookupNameAndType(name, signature)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ name_index = addUtf8(name);
+ signature_index = addUtf8(signature);
+ ret = index;
+ constants[index++] = new ConstantNameAndType(name_index, signature_index);
+
+ n_a_t_table.put(name + NAT_DELIM + signature, new Index(ret));
+ return ret;
+ }
+
+ private HashMap cp_table = new HashMap();
+
+ /**
+ * Look for ConstantMethodref in ConstantPool.
+ *
+ * @param class_name Where to find method
+ * @param method_name Guess what
+ * @param signature return and argument types
+ * @return index on success, -1 otherwise
+ */
+ public int lookupMethodref(String class_name, String method_name, String signature) {
+ Index index = (Index)cp_table.get(class_name + METHODREF_DELIM + method_name +
+ METHODREF_DELIM + signature);
+ return (index != null)? index.index : -1;
+ }
+
+ public int lookupMethodref(MethodGen method) {
+ return lookupMethodref(method.getClassName(), method.getName(),
+ method.getSignature());
+ }
+
+ /**
+ * Add a new Methodref constant to the ConstantPool, if it is not already
+ * in there.
+ *
+ * @param n Methodref string to add
+ * @return index of entry
+ */
+ public int addMethodref(String class_name, String method_name, String signature) {
+ int ret, class_index, name_and_type_index;
+
+ if((ret = lookupMethodref(class_name, method_name, signature)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ name_and_type_index = addNameAndType(method_name, signature);
+ class_index = addClass(class_name);
+ ret = index;
+ constants[index++] = new ConstantMethodref(class_index, name_and_type_index);
+
+ cp_table.put(class_name + METHODREF_DELIM + method_name +
+ METHODREF_DELIM + signature, new Index(ret));
+
+ return ret;
+ }
+
+ public int addMethodref(MethodGen method) {
+ return addMethodref(method.getClassName(), method.getName(),
+ method.getSignature());
+ }
+
+ /**
+ * Look for ConstantInterfaceMethodref in ConstantPool.
+ *
+ * @param class_name Where to find method
+ * @param method_name Guess what
+ * @param signature return and argument types
+ * @return index on success, -1 otherwise
+ */
+ public int lookupInterfaceMethodref(String class_name, String method_name, String signature) {
+ Index index = (Index)cp_table.get(class_name + IMETHODREF_DELIM + method_name +
+ IMETHODREF_DELIM + signature);
+ return (index != null)? index.index : -1;
+ }
+
+ public int lookupInterfaceMethodref(MethodGen method) {
+ return lookupInterfaceMethodref(method.getClassName(), method.getName(),
+ method.getSignature());
+ }
+
+ /**
+ * Add a new InterfaceMethodref constant to the ConstantPool, if it is not already
+ * in there.
+ *
+ * @param n InterfaceMethodref string to add
+ * @return index of entry
+ */
+ public int addInterfaceMethodref(String class_name, String method_name, String signature) {
+ int ret, class_index, name_and_type_index;
+
+ if((ret = lookupInterfaceMethodref(class_name, method_name, signature)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ class_index = addClass(class_name);
+ name_and_type_index = addNameAndType(method_name, signature);
+ ret = index;
+ constants[index++] = new ConstantInterfaceMethodref(class_index, name_and_type_index);
+
+ cp_table.put(class_name + IMETHODREF_DELIM + method_name +
+ IMETHODREF_DELIM + signature, new Index(ret));
+
+ return ret;
+ }
+
+ public int addInterfaceMethodref(MethodGen method) {
+ return addInterfaceMethodref(method.getClassName(), method.getName(),
+ method.getSignature());
+ }
+
+ /**
+ * Look for ConstantFieldref in ConstantPool.
+ *
+ * @param class_name Where to find method
+ * @param field_name Guess what
+ * @param signature return and argument types
+ * @return index on success, -1 otherwise
+ */
+ public int lookupFieldref(String class_name, String field_name, String signature) {
+ Index index = (Index)cp_table.get(class_name + FIELDREF_DELIM + field_name +
+ FIELDREF_DELIM + signature);
+ return (index != null)? index.index : -1;
+ }
+
+ /**
+ * Add a new Fieldref constant to the ConstantPool, if it is not already
+ * in there.
+ *
+ * @param n Fieldref string to add
+ * @return index of entry
+ */
+ public int addFieldref(String class_name, String field_name, String signature) {
+ int ret;
+ int class_index, name_and_type_index;
+
+ if((ret = lookupFieldref(class_name, field_name, signature)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ class_index = addClass(class_name);
+ name_and_type_index = addNameAndType(field_name, signature);
+ ret = index;
+ constants[index++] = new ConstantFieldref(class_index, name_and_type_index);
+
+ cp_table.put(class_name + FIELDREF_DELIM + field_name + FIELDREF_DELIM + signature, new Index(ret));
+
+ return ret;
+ }
+
+ /**
+ * @param i index in constant pool
+ * @return constant pool entry at index i
+ */
+ public Constant getConstant(int i) { return constants[i]; }
+
+ /**
+ * Use with care!
+ *
+ * @param i index in constant pool
+ * @param c new constant pool entry at index i
+ */
+ public void setConstant(int i, Constant c) { constants[i] = c; }
+
+ /**
+ * @return intermediate constant pool
+ */
+ public ConstantPool getConstantPool() {
+ return new ConstantPool(constants);
+ }
+
+ /**
+ * @return current size of constant pool
+ */
+ public int getSize() {
+ return index;
+ }
+
+ /**
+ * @return constant pool with proper length
+ */
+ public ConstantPool getFinalConstantPool() {
+ Constant[] cs = new Constant[index];
+
+ System.arraycopy(constants, 0, cs, 0, index);
+
+ return new ConstantPool(cs);
+ }
+
+ /**
+ * @return String representation.
+ */
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ for(int i=1; i < index; i++)
+ buf.append(i + ")" + constants[i] + "\n");
+
+ return buf.toString();
+ }
+
+ /** Import constant from another ConstantPool and return new index.
+ */
+ public int addConstant(Constant c, ConstantPoolGen cp) {
+ Constant[] constants = cp.getConstantPool().getConstantPool();
+
+ switch(c.getTag()) {
+ case Constants.CONSTANT_String: {
+ ConstantString s = (ConstantString)c;
+ ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()];
+
+ return addString(u8.getBytes());
+ }
+
+ case Constants.CONSTANT_Class: {
+ ConstantClass s = (ConstantClass)c;
+ ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()];
+
+ return addClass(u8.getBytes());
+ }
+
+ case Constants.CONSTANT_NameAndType: {
+ ConstantNameAndType n = (ConstantNameAndType)c;
+ ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()];
+ ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()];
+
+ return addNameAndType(u8.getBytes(), u8_2.getBytes());
+ }
+
+ case Constants.CONSTANT_Utf8:
+ return addUtf8(((ConstantUtf8)c).getBytes());
+
+ case Constants.CONSTANT_Double:
+ return addDouble(((ConstantDouble)c).getBytes());
+
+ case Constants.CONSTANT_Float:
+ return addFloat(((ConstantFloat)c).getBytes());
+
+ case Constants.CONSTANT_Long:
+ return addLong(((ConstantLong)c).getBytes());
+
+ case Constants.CONSTANT_Integer:
+ return addInteger(((ConstantInteger)c).getBytes());
+
+ case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref:
+ case Constants.CONSTANT_Fieldref: {
+ ConstantCP m = (ConstantCP)c;
+ ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()];
+ ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()];
+ ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()];
+ String class_name = u8.getBytes().replace('/', '.');
+
+ u8 = (ConstantUtf8)constants[n.getNameIndex()];
+ String name = u8.getBytes();
+
+ u8 = (ConstantUtf8)constants[n.getSignatureIndex()];
+ String signature = u8.getBytes();
+
+ switch(c.getTag()) {
+ case Constants.CONSTANT_InterfaceMethodref:
+ return addInterfaceMethodref(class_name, name, signature);
+
+ case Constants.CONSTANT_Methodref:
+ return addMethodref(class_name, name, signature);
+
+ case Constants.CONSTANT_Fieldref:
+ return addFieldref(class_name, name, signature);
+
+ default: // Never reached
+ throw new RuntimeException("Unknown constant type " + c);
+ }
+ }
+
+ default: // Never reached
+ throw new RuntimeException("Unknown constant type " + c);
+ }
+ }
+}
diff --git a/openjdk8/src/main/docker/Dockerfile b/openjdk8/src/main/docker/Dockerfile
index c8fee1ce..69d67c59 100644
--- a/openjdk8/src/main/docker/Dockerfile
+++ b/openjdk8/src/main/docker/Dockerfile
@@ -37,6 +37,37 @@ RUN \
&& apt-get clean \
&& rm /var/lib/apt/lists/*_*
+# Below code is a temporary fix to patch a bug and address b/244448607.
+# It should be removed once openjdk-8-8u342-b07-1 is promoted to stable (strech) debian package source.
+ARG JAVA_PATCH_SRC=/tmp/java/src
+ARG JAVA_PATCH_OUTPUT=/tmp/java/output
+ARG JAVA_PATCH_BACKUP=/tmp/java/backup
+ARG ORIG_RT_JAR_PATH=/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar
+
+RUN mkdir -p $JAVA_PATCH_SRC \
+ && mkdir -p $JAVA_PATCH_OUTPUT \
+ && mkdir -p $JAVA_PATCH_BACKUP
+
+# COPY patched files
+COPY ConstantPoolGen.java $JAVA_PATCH_SRC/com/sun/org/apache/bcel/internal/generic/
+COPY ConstantPool.java $JAVA_PATCH_SRC/com/sun/org/apache/bcel/internal/classfile/
+
+# Build and Replace
+RUN cp $ORIG_RT_JAR_PATH $JAVA_PATCH_BACKUP/original_rt.jar \
+ # Unpack existing rt.jar to the output folder (used as the base drop folder)
+ && cd $JAVA_PATCH_OUTPUT \
+ && jar xf /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar \
+ # Compile the patched files and drop them in the output folder
+ && cd $JAVA_PATCH_SRC \
+ && javac -d $JAVA_PATCH_OUTPUT -cp $ORIG_RT_JAR_PATH $(find * -name '*.java') \
+ # Pack the output folder which now has the new patched classes
+ && cd $JAVA_PATCH_OUTPUT \
+ && jar cvf $JAVA_PATCH_BACKUP/new_rt.jar . \
+ # Replace the live rt.jar with the new rt.jar
+ && cp $JAVA_PATCH_BACKUP/new_rt.jar $ORIG_RT_JAR_PATH
+ ## clean-up
+ #&& rm -rf /tmp/java
+
# Add the Stackdriver Debugger libraries
ADD https://storage.googleapis.com/cloud-debugger/appengine-java/current/cdbg_java_agent.tar.gz /opt/cdbg/
# Add the Stackdriver Profiler libraries