16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.misc; 27 28 import java.io.File; 29 import java.io.IOException; 30 import java.io.FilePermission; 31 import java.net.URL; 32 import java.net.URLClassLoader; 33 import java.net.MalformedURLException; 34 import java.net.URLStreamHandler; 35 import java.net.URLStreamHandlerFactory; 36 import java.util.HashSet; 37 import java.util.StringTokenizer; 38 import java.util.Set; 39 import java.util.Vector; 40 import java.security.AccessController; 41 import java.security.PrivilegedAction; 42 import java.security.PrivilegedExceptionAction; 43 import java.security.AccessControlContext; 44 import java.security.PermissionCollection; 45 import java.security.Permissions; 46 import java.security.Permission; 47 import java.security.ProtectionDomain; 48 import java.security.CodeSource; 49 import sun.security.util.SecurityConstants; 50 import sun.net.www.ParseUtil; 51 52 /** 53 * This class is used by the system to launch the main application. 54 Launcher */ 55 public class Launcher { 56 private static URLStreamHandlerFactory factory = new Factory(); 57 private static Launcher launcher = new Launcher(); 58 private static String bootClassPath = 59 System.getProperty("sun.boot.class.path"); 60 61 public static Launcher getLauncher() { 62 return launcher; 63 } 64 65 private ClassLoader loader; 66 67 public Launcher() { 68 // Create the extension class loader 69 ClassLoader extcl; 70 try { 71 extcl = ExtClassLoader.getExtClassLoader(); 72 } catch (IOException e) { 73 throw new InternalError( 74 "Could not create extension class loader", e); 75 } 76 77 // Now create the class loader to use to launch the application 78 try { 79 loader = AppClassLoader.getAppClassLoader(extcl); 112 /* 113 * Returns the class loader used to launch the main application. 114 */ 115 public ClassLoader getClassLoader() { 116 return loader; 117 } 118 119 /* 120 * The class loader used for loading installed extensions. 121 */ 122 static class ExtClassLoader extends URLClassLoader { 123 124 static { 125 ClassLoader.registerAsParallelCapable(); 126 } 127 128 /** 129 * create an ExtClassLoader. The ExtClassLoader is created 130 * within a context that limits which files it can read 131 */ 132 public static ExtClassLoader getExtClassLoader() throws IOException 133 { 134 final File[] dirs = getExtDirs(); 135 136 try { 137 // Prior implementations of this doPrivileged() block supplied 138 // aa synthesized ACC via a call to the private method 139 // ExtClassLoader.getContext(). 140 141 return AccessController.doPrivileged( 142 new PrivilegedExceptionAction<ExtClassLoader>() { 143 public ExtClassLoader run() throws IOException { 144 int len = dirs.length; 145 for (int i = 0; i < len; i++) { 146 MetaIndex.registerDirectory(dirs[i]); 147 } 148 return new ExtClassLoader(dirs); 149 } 150 }); 151 } catch (java.security.PrivilegedActionException e) { 152 throw (IOException) e.getException(); 153 } 154 } 155 156 void addExtURL(URL url) { 157 super.addURL(url); 158 } 159 160 /* 161 * Creates a new ExtClassLoader for the specified directories. 162 */ 163 public ExtClassLoader(File[] dirs) throws IOException { 164 super(getExtURLs(dirs), null, factory); 165 } 166 167 private static File[] getExtDirs() { 168 String s = System.getProperty("java.ext.dirs"); 169 File[] dirs; 170 if (s != null) { 171 StringTokenizer st = 172 new StringTokenizer(s, File.pathSeparator); 173 int count = st.countTokens(); 174 dirs = new File[count]; 175 for (int i = 0; i < count; i++) { 176 dirs[i] = new File(st.nextToken()); 177 } 178 } else { 179 dirs = new File[0]; 180 } 181 return dirs; 182 } 183 184 private static URL[] getExtURLs(File[] dirs) throws IOException { 185 Vector<URL> urls = new Vector<URL>(); 186 for (int i = 0; i < dirs.length; i++) { 187 String[] files = dirs[i].list(); 188 if (files != null) { 189 for (int j = 0; j < files.length; j++) { 190 if (!files[j].equals("meta-index")) { 191 File f = new File(dirs[i], files[j]); 192 urls.add(getFileURL(f)); 193 } 194 } 195 } 196 } 197 URL[] ua = new URL[urls.size()]; 198 urls.copyInto(ua); 199 return ua; 200 } 201 202 /* 203 * Searches the installed extension directories for the specified 204 * library name. For each extension directory, we first look for 205 * the native library in the subdirectory whose name is the value 206 * of the system property <code>os.arch</code>. Failing that, we 207 * look in the extension directory itself. 208 */ 209 public String findLibrary(String name) { 210 final String libname = System.mapLibraryName(name); 211 URL[] urls = super.getURLs(); 212 File prevDir = null; 213 for (int i = 0; i < urls.length; i++) { 214 // Get the ext directory from the URL 215 File dir = new File(urls[i].getPath()).getParentFile(); 216 if (dir != null && !dir.equals(prevDir)) { 217 // Look in architecture-specific subdirectory first 218 // Read from the saved system properties to avoid deadlock 219 final String arch = VM.getSavedProperty("os.arch"); 220 String pathname = AccessController.doPrivileged( 221 new PrivilegedAction<String>() { 222 public String run() { 223 if (arch != null) { 224 File file = new File(new File(dir, arch), libname); 225 if (file.exists()) { 226 return file.getAbsolutePath(); 227 } 228 } 229 // Then check the extension directory 230 File file = new File(dir, libname); 231 if (file.exists()) { 232 return file.getAbsolutePath(); 233 } 234 return null; 235 } 236 }); 237 if (pathname != null) { 238 return pathname; 239 } 240 } 241 prevDir = dir; 242 } 243 return null; 244 } 245 246 private static AccessControlContext getContext(File[] dirs) 247 throws IOException 248 { 249 PathPermissions perms = 250 new PathPermissions(dirs); 251 252 ProtectionDomain domain = new ProtectionDomain( 253 new CodeSource(perms.getCodeBase(), 254 (java.security.cert.Certificate[]) null), 255 perms); 256 257 AccessControlContext acc = 258 new AccessControlContext(new ProtectionDomain[] { domain }); 259 260 return acc; 261 } 262 } 263 264 /** 265 * The class loader used for loading from java.class.path. 266 * runs in a restricted security context. 267 */ 268 static class AppClassLoader extends URLClassLoader { 269 270 static { 271 ClassLoader.registerAsParallelCapable(); 272 } 273 274 public static ClassLoader getAppClassLoader(final ClassLoader extcl) 275 throws IOException 276 { 277 final String s = System.getProperty("java.class.path"); 278 final File[] path = (s == null) ? new File[0] : getClassPath(s, true); 279 280 // Note: on bugid 4256530 281 // Prior implementations of this doPrivileged() block supplied 282 // a rather restrictive ACC via a call to the private method 283 // AppClassLoader.getContext(). This proved overly restrictive 284 // when loading classes. Specifically it prevent 285 // accessClassInPackage.sun.* grants from being honored. 286 // 287 return AccessController.doPrivileged( 288 new PrivilegedAction<AppClassLoader>() { 289 public AppClassLoader run() { 290 URL[] urls = 291 (s == null) ? new URL[0] : pathToURLs(path); 292 return new AppClassLoader(urls, extcl); 293 } 294 }); 295 } 296 297 /* 298 * Creates a new AppClassLoader 299 */ 300 AppClassLoader(URL[] urls, ClassLoader parent) { 301 super(urls, parent, factory); 302 } 303 304 /** 305 * Override loadClass so we can checkPackageAccess. 306 */ 307 public Class<?> loadClass(String name, boolean resolve) 308 throws ClassNotFoundException 309 { 310 int i = name.lastIndexOf('.'); 311 if (i != -1) { 312 SecurityManager sm = System.getSecurityManager(); 313 if (sm != null) { 314 sm.checkPackageAccess(name.substring(0, i)); 315 } 316 } 317 return (super.loadClass(name, resolve)); 318 } 319 320 /** 321 * allow any classes loaded from classpath to exit the VM. 322 */ 323 protected PermissionCollection getPermissions(CodeSource codesource) 324 { 325 PermissionCollection perms = super.getPermissions(codesource); 326 perms.add(new RuntimePermission("exitVM")); 327 return perms; 328 } 329 330 /** 331 * This class loader supports dynamic additions to the class path 332 * at runtime. 333 * 334 * @see java.lang.instrument.Instrumentation#appendToSystemClassLoaderSearch 335 */ 336 private void appendToClassPathForInstrumentation(String path) { 337 assert(Thread.holdsLock(this)); 338 339 // addURL is a no-op if path already contains the URL 340 super.addURL( getFileURL(new File(path)) ); 341 } 342 343 /** 344 * create a context that can read any directories (recursively) 351 throws java.net.MalformedURLException 352 { 353 PathPermissions perms = 354 new PathPermissions(cp); 355 356 ProtectionDomain domain = 357 new ProtectionDomain(new CodeSource(perms.getCodeBase(), 358 (java.security.cert.Certificate[]) null), 359 perms); 360 361 AccessControlContext acc = 362 new AccessControlContext(new ProtectionDomain[] { domain }); 363 364 return acc; 365 } 366 } 367 368 private static class BootClassPathHolder { 369 static final URLClassPath bcp; 370 static { 371 URL[] urls; 372 if (bootClassPath != null) { 373 urls = AccessController.doPrivileged( 374 new PrivilegedAction<URL[]>() { 375 public URL[] run() { 376 // Skip empty path in boot class path i.e. not default to use CWD 377 File[] classPath = getClassPath(bootClassPath, false); 378 int len = classPath.length; 379 Set<File> seenDirs = new HashSet<File>(); 380 for (int i = 0; i < len; i++) { 381 File curEntry = classPath[i]; 382 // Negative test used to properly handle 383 // nonexistent jars on boot class path 384 if (!curEntry.isDirectory()) { 385 curEntry = curEntry.getParentFile(); 386 } 387 if (curEntry != null && seenDirs.add(curEntry)) { 388 MetaIndex.registerDirectory(curEntry); 389 } 390 } 391 return pathToURLs(classPath); 392 } 393 } 394 ); 395 } else { 396 urls = new URL[0]; 397 } 398 bcp = new URLClassPath(urls, factory); 399 } 400 } 401 402 public static URLClassPath getBootstrapClassPath() { 403 return BootClassPathHolder.bcp; 404 } 405 406 private static URL[] pathToURLs(File[] path) { 407 URL[] urls = new URL[path.length]; 408 for (int i = 0; i < path.length; i++) { 409 urls[i] = getFileURL(path[i]); 410 } 411 // DEBUG 412 //for (int i = 0; i < urls.length; i++) { 413 // System.out.println("urls[" + i + "] = " + '"' + urls[i] + '"'); 414 //} 415 return urls; 416 } 417 | 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.misc; 27 28 import java.io.File; 29 import java.io.IOException; 30 import java.io.FilePermission; 31 import java.net.URL; 32 import java.net.URLClassLoader; 33 import java.net.MalformedURLException; 34 import java.net.URLStreamHandler; 35 import java.net.URLStreamHandlerFactory; 36 import java.util.ArrayList; 37 import java.util.HashSet; 38 import java.util.List; 39 import java.util.StringTokenizer; 40 import java.util.Set; 41 import java.security.AccessController; 42 import java.security.PrivilegedAction; 43 import java.security.PrivilegedExceptionAction; 44 import java.security.AccessControlContext; 45 import java.security.PermissionCollection; 46 import java.security.Permissions; 47 import java.security.Permission; 48 import java.security.ProtectionDomain; 49 import java.security.CodeSource; 50 import sun.security.util.SecurityConstants; 51 import sun.net.www.ParseUtil; 52 53 /** 54 * This class is used by the system to launch the main application. 55 Launcher */ 56 public class Launcher { 57 58 // ensure URLClassPath for boot loader is initialized first 59 static { 60 URLClassPath ucp = BootClassPathHolder.bcp; 61 } 62 63 private static URLStreamHandlerFactory factory = new Factory(); 64 private static Launcher launcher = new Launcher(); 65 66 public static Launcher getLauncher() { 67 return launcher; 68 } 69 70 private ClassLoader loader; 71 72 public Launcher() { 73 // Create the extension class loader 74 ClassLoader extcl; 75 try { 76 extcl = ExtClassLoader.getExtClassLoader(); 77 } catch (IOException e) { 78 throw new InternalError( 79 "Could not create extension class loader", e); 80 } 81 82 // Now create the class loader to use to launch the application 83 try { 84 loader = AppClassLoader.getAppClassLoader(extcl); 117 /* 118 * Returns the class loader used to launch the main application. 119 */ 120 public ClassLoader getClassLoader() { 121 return loader; 122 } 123 124 /* 125 * The class loader used for loading installed extensions. 126 */ 127 static class ExtClassLoader extends URLClassLoader { 128 129 static { 130 ClassLoader.registerAsParallelCapable(); 131 } 132 133 /** 134 * create an ExtClassLoader. The ExtClassLoader is created 135 * within a context that limits which files it can read 136 */ 137 public static ExtClassLoader getExtClassLoader() throws IOException { 138 try { 139 // Prior implementations of this doPrivileged() block supplied 140 // aa synthesized ACC via a call to the private method 141 // ExtClassLoader.getContext(). 142 143 return AccessController.doPrivileged( 144 new PrivilegedExceptionAction<ExtClassLoader>() { 145 public ExtClassLoader run() throws IOException { 146 // ext modules linked into image 147 String home = System.getProperty("java.home"); 148 File dir = new File(new File(home, "lib"), "modules"); 149 File jimage = new File(dir, "extmodules.jimage"); 150 151 File jfxrt = new File(new File(home, "lib"), "jfxrt.jar"); 152 File[] files = jfxrt.exists() ? new File[] {jimage, jfxrt} 153 : new File[] {jimage}; 154 return new ExtClassLoader(files); 155 } 156 }); 157 } catch (java.security.PrivilegedActionException e) { 158 throw (IOException) e.getException(); 159 } 160 } 161 162 void addExtURL(URL url) { 163 super.addURL(url); 164 } 165 166 /* 167 * Creates a new ExtClassLoader for the specified directories. 168 */ 169 public ExtClassLoader(File[] files) throws IOException { 170 super(getExtURLs(files), null, factory); 171 } 172 173 private static URL[] getExtURLs(File[] files) throws IOException { 174 List<URL> urls = new ArrayList<>(); 175 for (File f : files) { 176 urls.add(getFileURL(f)); 177 } 178 return urls.toArray(new URL[0]); 179 } 180 181 private static AccessControlContext getContext(File[] dirs) 182 throws IOException 183 { 184 PathPermissions perms = 185 new PathPermissions(dirs); 186 187 ProtectionDomain domain = new ProtectionDomain( 188 new CodeSource(perms.getCodeBase(), 189 (java.security.cert.Certificate[]) null), 190 perms); 191 192 AccessControlContext acc = 193 new AccessControlContext(new ProtectionDomain[] { domain }); 194 195 return acc; 196 } 197 } 198 199 /** 200 * The class loader used for loading from java.class.path. 201 * runs in a restricted security context. 202 */ 203 static class AppClassLoader extends URLClassLoader { 204 205 static { 206 ClassLoader.registerAsParallelCapable(); 207 } 208 209 public static ClassLoader getAppClassLoader(final ClassLoader extcl) 210 throws IOException 211 { 212 // modules linked into image are prepended to class path 213 String home = System.getProperty("java.home"); 214 File dir = new File(new File(home, "lib"), "modules"); 215 String jimage = new File(dir, "appmodules.jimage").getPath(); 216 217 String cp = System.getProperty("java.class.path"); 218 if (cp == null) { 219 cp = jimage; 220 } else { 221 cp = jimage + File.pathSeparator + cp; 222 } 223 final File[] path = getClassPath(cp, true); 224 225 // Note: on bugid 4256530 226 // Prior implementations of this doPrivileged() block supplied 227 // a rather restrictive ACC via a call to the private method 228 // AppClassLoader.getContext(). This proved overly restrictive 229 // when loading classes. Specifically it prevent 230 // accessClassInPackage.sun.* grants from being honored. 231 // 232 return AccessController.doPrivileged( 233 new PrivilegedAction<AppClassLoader>() { 234 public AppClassLoader run() { 235 URL[] urls = pathToURLs(path); 236 return new AppClassLoader(urls, extcl); 237 } 238 }); 239 } 240 241 /* 242 * Creates a new AppClassLoader 243 */ 244 AppClassLoader(URL[] urls, ClassLoader parent) { 245 super(urls, parent, factory); 246 } 247 248 /** 249 * Override loadClass so we can checkPackageAccess. 250 */ 251 public Class<?> loadClass(String name, boolean resolve) 252 throws ClassNotFoundException 253 { 254 int i = name.lastIndexOf('.'); 255 if (i != -1) { 256 SecurityManager sm = System.getSecurityManager(); 257 if (sm != null) { 258 sm.checkPackageAccess(name.substring(0, i)); 259 } 260 } 261 return (super.loadClass(name, resolve)); 262 } 263 264 /** 265 * allow any classes loaded from classpath to exit the VM. 266 */ 267 protected PermissionCollection getPermissions(CodeSource codesource) { 268 PermissionCollection perms = super.getPermissions(codesource); 269 perms.add(new RuntimePermission("exitVM")); 270 return perms; 271 } 272 273 /** 274 * This class loader supports dynamic additions to the class path 275 * at runtime. 276 * 277 * @see java.lang.instrument.Instrumentation#appendToSystemClassLoaderSearch 278 */ 279 private void appendToClassPathForInstrumentation(String path) { 280 assert(Thread.holdsLock(this)); 281 282 // addURL is a no-op if path already contains the URL 283 super.addURL( getFileURL(new File(path)) ); 284 } 285 286 /** 287 * create a context that can read any directories (recursively) 294 throws java.net.MalformedURLException 295 { 296 PathPermissions perms = 297 new PathPermissions(cp); 298 299 ProtectionDomain domain = 300 new ProtectionDomain(new CodeSource(perms.getCodeBase(), 301 (java.security.cert.Certificate[]) null), 302 perms); 303 304 AccessControlContext acc = 305 new AccessControlContext(new ProtectionDomain[] { domain }); 306 307 return acc; 308 } 309 } 310 311 private static class BootClassPathHolder { 312 static final URLClassPath bcp; 313 static { 314 URL[] urls = AccessController.doPrivileged( 315 new PrivilegedAction<URL[]>() { 316 public URL[] run() { 317 String bootClassPath = System.getProperty("sun.boot.class.path"); 318 if (bootClassPath == null) 319 return new URL[0]; 320 // Skip empty path in boot class path i.e. not default to use CWD 321 File[] classPath = getClassPath(bootClassPath, false); 322 int len = classPath.length; 323 Set<File> seenDirs = new HashSet<File>(); 324 for (int i = 0; i < len; i++) { 325 File curEntry = classPath[i]; 326 // Negative test used to properly handle 327 // nonexistent jars on boot class path 328 if (!curEntry.isDirectory()) { 329 curEntry = curEntry.getParentFile(); 330 } 331 if (curEntry != null && seenDirs.add(curEntry)) { 332 MetaIndex.registerDirectory(curEntry); 333 } 334 } 335 return pathToURLs(classPath); 336 } 337 } 338 ); 339 bcp = new URLClassPath(urls, factory); 340 } 341 } 342 343 public static URLClassPath getBootstrapClassPath() { 344 return BootClassPathHolder.bcp; 345 } 346 347 private static URL[] pathToURLs(File[] path) { 348 URL[] urls = new URL[path.length]; 349 for (int i = 0; i < path.length; i++) { 350 urls[i] = getFileURL(path[i]); 351 } 352 // DEBUG 353 //for (int i = 0; i < urls.length; i++) { 354 // System.out.println("urls[" + i + "] = " + '"' + urls[i] + '"'); 355 //} 356 return urls; 357 } 358 |