Mercurial > hg > graal-jvmci-8
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 } |