Mercurial > hg > truffle
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 } |