1eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin/**
2eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin * Copyright 2006-2017 the original author or authors.
3eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin *
4eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License");
5eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin * you may not use this file except in compliance with the License.
6eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin * You may obtain a copy of the License at
7eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin *
8eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin *     http://www.apache.org/licenses/LICENSE-2.0
9eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin *
10eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin * Unless required by applicable law or agreed to in writing, software
11eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS,
12eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin * See the License for the specific language governing permissions and
14eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin * limitations under the License.
15eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin */
16eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffinpackage org.objenesis.instantiator.sun;
17eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
18eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffinimport java.io.ByteArrayOutputStream;
19eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffinimport java.io.DataOutputStream;
20eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffinimport java.io.IOException;
21eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
22eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffinimport org.objenesis.ObjenesisException;
23eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffinimport org.objenesis.instantiator.ObjectInstantiator;
24eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffinimport org.objenesis.instantiator.annotations.Instantiator;
25eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffinimport org.objenesis.instantiator.annotations.Typology;
26eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffinimport org.objenesis.instantiator.basic.ClassDefinitionUtils;
27eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
28eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffinimport static org.objenesis.instantiator.basic.ClassDefinitionUtils.*;
29eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
30eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin/**
31eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin * This instantiator will correctly bypass the constructors by instantiating the class using the default
32eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin * constructor from Object. It will be allowed to do so by extending {@code MagicAccessorImpl} which prevents
33eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin * its children to be verified by the class loader
34eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin *
35eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin * @author Henri Tremblay
36eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin */
37eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin@Instantiator(Typology.STANDARD)
38eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffinpublic class MagicInstantiator<T> implements ObjectInstantiator<T> {
39eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
40eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_CLASS_THIS = 1;
41eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_CLASS_SUPERCLASS = 2;
42eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_UTF8_CONSTRUCTOR_NAME = 3;
43eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_UTF8_CONSTRUCTOR_DESC = 4;
44eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_UTF8_CODE_ATTRIBUTE = 5;
45eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_UTF8_INSTANTIATOR_CLASS = 7;
46eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_UTF8_SUPERCLASS = 8;
47eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_CLASS_INTERFACE = 9;
48eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_UTF8_INTERFACE = 10;
49eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_UTF8_NEWINSTANCE_NAME = 11;
50eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_UTF8_NEWINSTANCE_DESC = 12;
51eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_METHODREF_OBJECT_CONSTRUCTOR = 13;
52eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_CLASS_OBJECT = 14;
53eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_UTF8_OBJECT = 15;
54eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_NAMEANDTYPE_DEFAULT_CONSTRUCTOR = 16;
55eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_CLASS_TYPE = 17;
56eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int INDEX_UTF8_TYPE = 18;
57eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
58eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static int CONSTANT_POOL_COUNT = 19;
59eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
60eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final byte[] CONSTRUCTOR_CODE = { OPS_aload_0, OPS_invokespecial, 0, INDEX_METHODREF_OBJECT_CONSTRUCTOR, OPS_return};
61eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int CONSTRUCTOR_CODE_ATTRIBUTE_LENGTH = 12 + CONSTRUCTOR_CODE.length;
62eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
63eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final byte[] NEWINSTANCE_CODE = { OPS_new, 0, INDEX_CLASS_TYPE, OPS_dup, OPS_invokespecial, 0, INDEX_METHODREF_OBJECT_CONSTRUCTOR, OPS_areturn};
64eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final int NEWINSTANCE_CODE_ATTRIBUTE_LENGTH = 12 + NEWINSTANCE_CODE.length;
65eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
66eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final String CONSTRUCTOR_NAME = "<init>";
67eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private static final String CONSTRUCTOR_DESC = "()V";
68eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
69eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private ObjectInstantiator<T> instantiator;
70eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
71eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   public MagicInstantiator(Class<T> type) {
72eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      instantiator = newInstantiatorOf(type);
73eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   }
74eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
75eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   /**
76eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    * Get the underlying instantiator.
77eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    *
78eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    * {@link MagicInstantiator} is a wrapper around another object
79eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    * which implements {@link ObjectInstantiator} interface.
80eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    * This method exposes that instantiator.
81eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    *
82eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    * @return the underlying instantiator
83eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    */
84eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   public ObjectInstantiator<T> getInstantiator() {
85eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      return instantiator;
86eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   }
87eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
88eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private <T> ObjectInstantiator<T> newInstantiatorOf(Class<T> type) {
89eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      String suffix = type.getSimpleName();
90eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      String className = getClass().getName() + "$$$" + suffix;
91eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
92eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      Class<ObjectInstantiator<T>> clazz = getExistingClass(getClass().getClassLoader(), className);
93eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
94eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      if(clazz == null) {
95eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         byte[] classBytes = writeExtendingClass(type, className);
96eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
97eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         try {
98eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin            clazz = ClassDefinitionUtils.defineClass(className, classBytes, getClass().getClassLoader());
99eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         } catch (Exception e) {
100eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin            throw new ObjenesisException(e);
101eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         }
102eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      }
103eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
104eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      try {
105eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         return clazz.newInstance();
106eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      } catch (InstantiationException e) {
107eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         throw new ObjenesisException(e);
108eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      } catch (IllegalAccessException e) {
109eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         throw new ObjenesisException(e);
110eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      }
111eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   }
112eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
113eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   /**
114eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    * Will generate the bytes for a class extending the type passed in parameter. This class will
115eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    * only have an empty default constructor
116eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    *
117eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    * @param type type to extend
118eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    * @param className name of the wrapped instantiator class
119eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    * @return the byte for the class
120eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    * @throws ObjenesisException is something goes wrong
121eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin    */
122eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   private byte[] writeExtendingClass(Class<?> type, String className) {
123eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      String clazz = classNameToInternalClassName(className);
124eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
125eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      DataOutputStream in = null;
126eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      ByteArrayOutputStream bIn = new ByteArrayOutputStream(1000); // 1000 should be large enough to fit the entire class
127eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      try {
128eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in = new DataOutputStream(bIn);
129eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
130eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.write(MAGIC);
131eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.write(VERSION);
132eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(CONSTANT_POOL_COUNT);
133eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
134eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // set all the constant pool here
135eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
136eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 1. class
137eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Class);
138eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_UTF8_INSTANTIATOR_CLASS);
139eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
140eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 2. super class
141eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Class);
142eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_UTF8_SUPERCLASS);
143eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
144eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 3. default constructor name
145eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Utf8);
146eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeUTF(CONSTRUCTOR_NAME);
147eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
148eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 4. default constructor description
149eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Utf8);
150eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeUTF(CONSTRUCTOR_DESC);
151eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
152eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 5. Code
153eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Utf8);
154eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeUTF("Code");
155eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
156eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 6. Class name
157eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Utf8);
158eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeUTF("L" + clazz + ";");
159eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
160eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 7. Class name (again)
161eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Utf8);
162eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeUTF(clazz);
163eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
164eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 8. Superclass name
165eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Utf8);
166eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin//         in.writeUTF("java/lang/Object");
167eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeUTF("sun/reflect/MagicAccessorImpl");
168eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
169eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 9. ObjectInstantiator interface
170eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Class);
171eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_UTF8_INTERFACE);
172eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
173eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 10. ObjectInstantiator name
174eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Utf8);
175eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeUTF(ObjectInstantiator.class.getName().replace('.', '/'));
176eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
177eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 11. newInstance name
178eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Utf8);
179eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeUTF("newInstance");
180eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
181eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 12. newInstance desc
182eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Utf8);
183eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeUTF("()Ljava/lang/Object;");
184eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
185eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 13. Methodref to the Object constructor
186eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Methodref);
187eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_CLASS_OBJECT);
188eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_NAMEANDTYPE_DEFAULT_CONSTRUCTOR);
189eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
190eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 14. Object class
191eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Class);
192eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_UTF8_OBJECT);
193eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
194eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 15. Object class name
195eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Utf8);
196eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeUTF("java/lang/Object");
197eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
198eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 16. Default constructor name and type
199eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_NameAndType);
200eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME);
201eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC);
202eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
203eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 17. Type to instantiate class
204eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Class);
205eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_UTF8_TYPE);
206eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
207eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // 18. Type to instantiate name
208eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeByte(CONSTANT_Utf8);
209eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeUTF(classNameToInternalClassName(type.getName()));
210eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
211eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // end of constant pool
212eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
213eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // access flags: We want public, ACC_SUPER is always there
214eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(ACC_PUBLIC | ACC_SUPER | ACC_FINAL);
215eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
216eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // this class index in the constant pool
217eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_CLASS_THIS);
218eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
219eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // super class index in the constant pool
220eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_CLASS_SUPERCLASS);
221eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
222eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // interfaces implemented count (we have none)
223eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(1);
224eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_CLASS_INTERFACE);
225eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
226eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // fields count (we have none)
227eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(0);
228eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
229eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // method count (we have two: the default constructor and newInstance)
230eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(2);
231eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
232eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // default constructor method_info
233eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(ACC_PUBLIC);
234eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME); // index of the method name (<init>)
235eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC); // index of the description
236eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(1); // number of attributes: only one, the code
237eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
238eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // code attribute of the default constructor
239eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_UTF8_CODE_ATTRIBUTE);
240eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeInt(CONSTRUCTOR_CODE_ATTRIBUTE_LENGTH); // attribute length
241eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(0); // max_stack
242eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(1); // max_locals
243eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeInt(CONSTRUCTOR_CODE.length); // code length
244eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.write(CONSTRUCTOR_CODE);
245eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(0); // exception_table_length = 0
246eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(0); // attributes count = 0, no need to have LineNumberTable and LocalVariableTable
247eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
248eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // newInstance method_info
249eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(ACC_PUBLIC);
250eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_UTF8_NEWINSTANCE_NAME); // index of the method name (newInstance)
251eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_UTF8_NEWINSTANCE_DESC); // index of the description
252eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(1); // number of attributes: only one, the code
253eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
254eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // code attribute of newInstance
255eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(INDEX_UTF8_CODE_ATTRIBUTE);
256eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeInt(NEWINSTANCE_CODE_ATTRIBUTE_LENGTH); // attribute length
257eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(2); // max_stack
258eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(1); // max_locals
259eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeInt(NEWINSTANCE_CODE.length); // code length
260eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.write(NEWINSTANCE_CODE);
261eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(0); // exception_table_length = 0
262eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(0); // attributes count = 0, no need to have LineNumberTable and LocalVariableTable
263eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
264eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         // class attributes
265eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         in.writeShort(0); // none. No need to have a source file attribute
266eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
267eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      } catch (IOException e) {
268eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         throw new ObjenesisException(e);
269eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      } finally {
270eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         if(in != null) {
271eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin            try {
272eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin               in.close();
273eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin            } catch (IOException e) {
274eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin               throw new ObjenesisException(e);
275eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin            }
276eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin         }
277eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      }
278eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
279eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      return bIn.toByteArray();
280eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   }
281eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin
282eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   public T newInstance() {
283eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin      return instantiator.newInstance();
284eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin   }
285eebfcaffb2d52b214abfdb1c0102395c88c9db54Paul Duffin}
286