comparison jvmci/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIClassLoaderFactory.java @ 24140:d4858e92c9b1

[GR-4077] support Graal.SDK on the boot class path and Truffle on a class path invisible to apps but visible to JVMCI
author Doug Simon <doug.simon@oracle.com>
date Tue, 13 Jun 2017 14:22:54 +0200
parents 450e0bafd83d
children d442ede93e4b
comparison
equal deleted inserted replaced
24139:0c5304ad61bd 24140:d4858e92c9b1
21 * questions. 21 * questions.
22 */ 22 */
23 package jdk.vm.ci.services; 23 package jdk.vm.ci.services;
24 24
25 import java.io.File; 25 import java.io.File;
26 import java.io.IOException;
26 import java.net.MalformedURLException; 27 import java.net.MalformedURLException;
27 import java.net.URL; 28 import java.net.URL;
28 import java.net.URLClassLoader; 29 import java.net.URLClassLoader;
30 import java.nio.file.Files;
31 import java.nio.file.Path;
32 import java.nio.file.Paths;
29 import java.util.ArrayList; 33 import java.util.ArrayList;
30 import java.util.List; 34 import java.util.List;
31 35
32 import sun.misc.VM; 36 import sun.misc.VM;
33 37
34 /** 38 /**
35 * Utility called from the VM to create and register a separate class loader for loading JVMCI 39 * Utility called from the VM to create and register a separate class loader for loading JVMCI
36 * classes (i.e., those in found in lib/jvmci/*.jar) as well as those available on the class path in 40 * classes (i.e., those in found in {@code <java.home>/lib/jvmci/*.jar)} as well as those available
37 * the {@code "jvmci.class.path.append"} system property. 41 * on the class path in the {@code "jvmci.class.path.append"} system property. The JVMCI class
42 * loader can optionally be given a parent other than the boot class loader as specified by
43 * {@link #getJVMCIParentClassLoader(Path)}.
38 */ 44 */
39 class JVMCIClassLoaderFactory { 45 class JVMCIClassLoaderFactory {
40 46
41 /** 47 /**
42 * Copy of the {@code UseJVMCIClassLoader} VM option. Set by the VM before the static 48 * Copy of the {@code UseJVMCIClassLoader} VM option. Set by the VM before the static
55 61
56 /** 62 /**
57 * Creates a new class loader for loading JVMCI classes. 63 * Creates a new class loader for loading JVMCI classes.
58 */ 64 */
59 private static ClassLoader newClassLoader() { 65 private static ClassLoader newClassLoader() {
60 URL[] urls = getJVMCIJarsUrls(); 66 Path jvmciDir = Paths.get(VM.getSavedProperty("java.home"), "lib", "jvmci");
61 ClassLoader parent = null; 67 if (!Files.isDirectory(jvmciDir)) {
68 throw new InternalError(jvmciDir + " does not exist or is not a directory");
69 }
70 URL[] urls = getJVMCIJarsUrls(jvmciDir);
71 ClassLoader parent = getJVMCIParentClassLoader(jvmciDir);
62 return URLClassLoader.newInstance(urls, parent); 72 return URLClassLoader.newInstance(urls, parent);
63 } 73 }
64 74
65 /** 75 /**
66 * Gets the URLs for lib/jvmci/*.jar. 76 * Creates a parent class loader for the JVMCI class loader. The class path for the loader is
77 * specified in the optional file {@code <java.home>/lib/jvmci/parentClassLoader.classpath}. If
78 * the file exists, its contents must be a well formed class path. Relative entries in the class
79 * path are resolved against {@code <java.home>/lib/jvmci}.
80 *
81 * @return {@code null} if {@code <java.home>/lib/jvmci/parentClassLoader.classpath} does not
82 * exist otherwise a {@link URLClassLoader} constructed from the class path in the file
67 */ 83 */
68 private static URL[] getJVMCIJarsUrls() { 84 private static ClassLoader getJVMCIParentClassLoader(Path jvmciDir) {
69 File javaHome = new File(VM.getSavedProperty("java.home")); 85 Path parentFile = jvmciDir.resolve("parentClassLoader.classpath");
70 File lib = new File(javaHome, "lib"); 86 if (Files.exists(parentFile)) {
71 File jvmci = new File(lib, "jvmci"); 87 String[] entries;
72 if (!jvmci.isDirectory()) { 88 try {
73 throw new InternalError(jvmci + " does not exist or is not a directory"); 89 entries = new String(Files.readAllBytes(parentFile)).trim().split(File.pathSeparator);
90 } catch (IOException e) {
91 throw new InternalError("Error reading " + parentFile.toAbsolutePath(), e);
92 }
93 URL[] urls = new URL[entries.length];
94 for (int i = 0; i < entries.length; i++) {
95 try {
96 // If entries[i] is already absolute, it will remain unchanged
97 urls[i] = jvmciDir.resolve(entries[i]).toFile().toURI().toURL();
98 } catch (MalformedURLException e) {
99 throw new InternalError(e);
100 }
101 }
102 ClassLoader parent = null;
103 return URLClassLoader.newInstance(urls, parent);
74 } 104 }
105 return null;
106 }
75 107
76 List<URL> urls = new ArrayList<>(); 108 /**
77 for (String fileName : jvmci.list()) { 109 * Gets the URLs for all jar files in the {@code jvmciDir} directory as well as the entries
110 * specified by the {@code "jvmci.class.path.append"} system property.
111 */
112 private static URL[] getJVMCIJarsUrls(Path jvmciDir) {
113 String[] dirEntries = jvmciDir.toFile().list();
114
115 String append = VM.getSavedProperty("jvmci.class.path.append");
116 String[] appendEntries = append != null ? append.split(File.pathSeparator) : new String[0];
117 List<URL> urls = new ArrayList<>(dirEntries.length + appendEntries.length);
118
119 for (String fileName : dirEntries) {
78 if (fileName.endsWith(".jar")) { 120 if (fileName.endsWith(".jar")) {
79 File file = new File(jvmci, fileName); 121 Path path = jvmciDir.resolve(fileName);
80 if (file.isDirectory()) { 122 if (Files.isDirectory(path)) {
81 continue; 123 continue;
82 } 124 }
83 try { 125 try {
84 urls.add(file.toURI().toURL()); 126 urls.add(path.toFile().toURI().toURL());
85 } catch (MalformedURLException e) { 127 } catch (MalformedURLException e) {
86 throw new InternalError(e); 128 throw new InternalError(e);
87 } 129 }
88 } 130 }
89 } 131 }
90 132 for (String path : appendEntries) {
91 String append = VM.getSavedProperty("jvmci.class.path.append"); 133 try {
92 if (append != null) { 134 urls.add(new File(path).toURI().toURL());
93 for (String entry : append.split(File.pathSeparator)) { 135 } catch (MalformedURLException e) {
94 File file = new File(entry); 136 throw new InternalError(e);
95 try {
96 urls.add(file.toURI().toURL());
97 } catch (MalformedURLException e) {
98 throw new InternalError(e);
99 }
100 } 137 }
101 } 138 }
102 139
103 return urls.toArray(new URL[urls.size()]); 140 return urls.toArray(new URL[urls.size()]);
104 } 141 }