5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 import java.io.DataInputStream;
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.FileWriter;
28 import java.io.IOException;
29 import java.io.PrintWriter;
30 import javax.tools.JavaCompiler;
31 import javax.tools.ToolProvider;
32
33 /**
34 * A class loader that generates new classes.
35 * The generated classes are made by first emitting java sources with nested
36 * static classes, these are then compiled and the class files are read back.
37 * Some efforts are made to make the class instances unique and of not insignificant
38 * size.
39 */
40 public class GeneratedClassLoader extends ClassLoader {
41 /**
42 * Holds a pair of class bytecodes and class name (for use with defineClass).
43 */
44 private static class GeneratedClass {
128 sb.append("private String str").append(i)
129 .append(" = \"")
130 .append(getBigString(i))
131 .append("\";");
132 }
133 sb.append("\n}");
134 }
135 sb.append("\n}");
136 return sb.toString();
137 }
138
139 private GeneratedClass[] getGeneratedClass(int sizeFactor, int numClasses) throws IOException {
140 int uniqueCount = getNextCount();
141 String src = generateSource(uniqueCount, sizeFactor, numClasses);
142 String className = getClassName(uniqueCount);
143 File file = new File(className + ".java");
144 try (PrintWriter pw = new PrintWriter(new FileWriter(file))) {
145 pw.append(src);
146 pw.flush();
147 }
148 int exitcode = javac.run(null, null, null, file.getCanonicalPath());
149 if (exitcode != 0) {
150 throw new RuntimeException("javac failure when compiling: " +
151 file.getCanonicalPath());
152 } else {
153 if (deleteFiles) {
154 file.delete();
155 }
156 }
157 GeneratedClass[] gc = new GeneratedClass[numClasses];
158 for (int i = 0; i < numClasses; ++i) {
159 String name = className + "$" + "Class" + i;
160 File classFile = new File(name + ".class");
161 byte[] bytes;
162 try (DataInputStream dis = new DataInputStream(new FileInputStream(classFile))) {
163 bytes = new byte[dis.available()];
164 dis.readFully(bytes);
165 }
166 if (deleteFiles) {
167 classFile.delete();
168 }
169 gc[i] = new GeneratedClass(bytes, name);
170 }
171 if (deleteFiles) {
|
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 import java.io.DataInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.FileWriter;
29 import java.io.IOException;
30 import java.io.PrintWriter;
31 import javax.tools.JavaCompiler;
32 import javax.tools.ToolProvider;
33
34 /**
35 * A class loader that generates new classes.
36 * The generated classes are made by first emitting java sources with nested
37 * static classes, these are then compiled and the class files are read back.
38 * Some efforts are made to make the class instances unique and of not insignificant
39 * size.
40 */
41 public class GeneratedClassLoader extends ClassLoader {
42 /**
43 * Holds a pair of class bytecodes and class name (for use with defineClass).
44 */
45 private static class GeneratedClass {
129 sb.append("private String str").append(i)
130 .append(" = \"")
131 .append(getBigString(i))
132 .append("\";");
133 }
134 sb.append("\n}");
135 }
136 sb.append("\n}");
137 return sb.toString();
138 }
139
140 private GeneratedClass[] getGeneratedClass(int sizeFactor, int numClasses) throws IOException {
141 int uniqueCount = getNextCount();
142 String src = generateSource(uniqueCount, sizeFactor, numClasses);
143 String className = getClassName(uniqueCount);
144 File file = new File(className + ".java");
145 try (PrintWriter pw = new PrintWriter(new FileWriter(file))) {
146 pw.append(src);
147 pw.flush();
148 }
149 ByteArrayOutputStream err = new ByteArrayOutputStream();
150 int exitcode = javac.run(null, null, err, file.getCanonicalPath());
151 if (exitcode != 0) {
152 // Print Error
153 System.err.print(err);
154 if (err.toString().contains("java.lang.OutOfMemoryError: Java heap space")) {
155 throw new OutOfMemoryError("javac failed with resources exhausted");
156 } else {
157 throw new RuntimeException("javac failure when compiling: " +
158 file.getCanonicalPath());
159 }
160 } else {
161 if (deleteFiles) {
162 file.delete();
163 }
164 }
165 GeneratedClass[] gc = new GeneratedClass[numClasses];
166 for (int i = 0; i < numClasses; ++i) {
167 String name = className + "$" + "Class" + i;
168 File classFile = new File(name + ".class");
169 byte[] bytes;
170 try (DataInputStream dis = new DataInputStream(new FileInputStream(classFile))) {
171 bytes = new byte[dis.available()];
172 dis.readFully(bytes);
173 }
174 if (deleteFiles) {
175 classFile.delete();
176 }
177 gc[i] = new GeneratedClass(bytes, name);
178 }
179 if (deleteFiles) {
|