comparison test/compiler/jsr292/methodHandleExceptions/ByteClassLoader.java @ 13403:9d15b81d5d1b

8016839: JSR292: AME instead of IAE when calling a method Summary: Catch missing-because-illegal case for itable entries and use an exception-throwing method instead of null. Reviewed-by: acorn, jrose, coleenp
author drchase
date Tue, 26 Nov 2013 18:16:04 -0500
parents dc261f466b6d
children
comparison
equal deleted inserted replaced
13397:e51d73189692 13403:9d15b81d5d1b
1 import java.io.BufferedOutputStream;
2 import java.io.FileNotFoundException;
3 import java.io.FileOutputStream;
4 import java.io.IOException;
5 import java.net.URL;
6 import java.net.URLClassLoader;
7 import java.util.jar.JarEntry;
8 import java.util.jar.JarOutputStream;
9
1 /* 10 /*
2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 11 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 13 *
5 * This code is free software; you can redistribute it and/or modify it 14 * This code is free software; you can redistribute it and/or modify it
21 * questions. 30 * questions.
22 * 31 *
23 */ 32 */
24 33
25 /** 34 /**
26 * A minimal classloader for loading bytecodes that could not result from 35 * A ByteClassLoader is used to define classes from collections of bytes, as
27 * properly compiled Java. 36 * well as loading classes in the usual way. It includes options to write the
37 * classes to files in a jar, or to read the classes from jars in a later or
38 * debugging run.
28 * 39 *
29 * @author dr2chase 40 * If Boolean property byteclassloader.verbose is true, be chatty about jar
41 * file operations.
42 *
30 */ 43 */
31 public class ByteClassLoader extends ClassLoader { 44 public class ByteClassLoader extends URLClassLoader {
45
46 final static boolean verbose
47 = Boolean.getBoolean("byteclassloader.verbose");
48
49 final boolean read;
50 final JarOutputStream jos;
51 final String jar_name;
52
53 /**
54 * Make a new ByteClassLoader.
55 *
56 * @param jar_name Basename of jar file to be read/written by this classloader.
57 * @param read If true, read classes from jar file instead of from parameter.
58 * @param write If true, write classes to jar files for offline study/use.
59 *
60 * @throws FileNotFoundException
61 * @throws IOException
62 */
63 public ByteClassLoader(String jar_name, boolean read, boolean write)
64 throws FileNotFoundException, IOException {
65 super(read
66 ? new URL[]{new URL("file:" + jar_name + ".jar")}
67 : new URL[0]);
68 this.read = read;
69 this.jar_name = jar_name;
70 this.jos = write
71 ? new JarOutputStream(
72 new BufferedOutputStream(
73 new FileOutputStream(jar_name + ".jar"))) : null;
74 if (read && write) {
75 throw new Error("At most one of read and write may be true.");
76 }
77 }
78
79 private static void writeJarredFile(JarOutputStream jos, String file, String suffix, byte[] bytes) {
80 String fileName = file.replace(".", "/") + "." + suffix;
81 JarEntry ze = new JarEntry(fileName);
82 try {
83 ze.setSize(bytes.length);
84 jos.putNextEntry(ze);
85 jos.write(bytes);
86 jos.closeEntry();
87 } catch (IOException e) {
88 throw new RuntimeException(e);
89 }
90 }
91
32 /** 92 /**
33 * (pre)load class name using classData for the definition. 93 * (pre)load class name using classData for the definition.
34 * 94 *
35 * @param name 95 * @param name
36 * @param classData 96 * @param classData
37 * @return 97 * @return
38 */ 98 */
39 public Class<?> loadBytes(String name, byte[] classData) { 99 public Class<?> loadBytes(String name, byte[] classData) throws ClassNotFoundException {
40 Class<?> clazz = defineClass(name, classData, 0, classData.length); 100 if (jos != null) {
41 resolveClass(clazz); 101 if (verbose) {
42 return clazz; 102 System.out.println("ByteClassLoader: writing " + name);
103 }
104 writeJarredFile(jos, name, "class", classData);
105 }
106
107 Class<?> clazz = null;
108 if (read) {
109 if (verbose) {
110 System.out.println("ByteClassLoader: reading " + name + " from " + jar_name);
111 }
112 clazz = loadClass(name);
113 } else {
114 clazz = defineClass(name, classData, 0, classData.length);
115 resolveClass(clazz);
116 }
117 return clazz;
118 }
119
120 public void close() {
121 if (jos != null) {
122 try {
123 if (verbose) {
124 System.out.println("ByteClassLoader: closing " + jar_name);
125 }
126 jos.close();
127 } catch (IOException ex) {
128 }
129 }
43 } 130 }
44 } 131 }