History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/misc/Launcher.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/misc/Launcher.java+587−0
@@ -0,0 +1,587 @@
1/*
2 * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
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
26package sun.misc;
27
28import java.io.File;
29import java.io.IOException;
30import java.io.FilePermission;
31import java.net.URL;
32import java.net.URLClassLoader;
33import java.net.MalformedURLException;
34import java.net.URLStreamHandler;
35import java.net.URLStreamHandlerFactory;
36import java.util.HashSet;
37import java.util.StringTokenizer;
38import java.util.Set;
39import java.util.Vector;
40import java.security.AccessController;
41import java.security.PrivilegedAction;
42import java.security.PrivilegedExceptionAction;
43import java.security.AccessControlContext;
44import java.security.PermissionCollection;
45import java.security.Permissions;
46import java.security.Permission;
47import java.security.ProtectionDomain;
48import java.security.CodeSource;
49import sun.security.util.SecurityConstants;
50import sun.net.www.ParseUtil;
51
52/**
53 * This class is used by the system to launch the main application.
54Launcher */
55public 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");
75 }
76
77 // Now create the class loader to use to launch the application
78 try {
79 loader = AppClassLoader.getAppClassLoader(extcl);
80 } catch (IOException e) {
81 throw new InternalError(
82 "Could not create application class loader");
83 }
84
85 // Also set the context class loader for the primordial thread.
86 Thread.currentThread().setContextClassLoader(loader);
87
88 // Finally, install a security manager if requested
89 String s = System.getProperty("java.security.manager");
90 if (s != null) {
91 SecurityManager sm = null;
92 if ("".equals(s) || "default".equals(s)) {
93 sm = new java.lang.SecurityManager();
94 } else {
95 try {
96 sm = (SecurityManager)loader.loadClass(s).newInstance();
97 } catch (IllegalAccessException e) {
98 } catch (InstantiationException e) {
99 } catch (ClassNotFoundException e) {
100 } catch (ClassCastException e) {
101 }
102 }
103 if (sm != null) {
104 System.setSecurityManager(sm);
105 } else {
106 throw new InternalError(
107 "Could not create SecurityManager: " + s);
108 }
109 }
110 }
111
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 name = 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 String arch = VM.getSavedProperty("os.arch");
220 if (arch != null) {
221 File file = new File(new File(dir, arch), name);
222 if (file.exists()) {
223 return file.getAbsolutePath();
224 }
225 }
226 // Then check the extension directory
227 File file = new File(dir, name);
228 if (file.exists()) {
229 return file.getAbsolutePath();
230 }
231 }
232 prevDir = dir;
233 }
234 return null;
235 }
236
237 private static AccessControlContext getContext(File[] dirs)
238 throws IOException
239 {
240 PathPermissions perms =
241 new PathPermissions(dirs);
242
243 ProtectionDomain domain = new ProtectionDomain(
244 new CodeSource(perms.getCodeBase(),
245 (java.security.cert.Certificate[]) null),
246 perms);
247
248 AccessControlContext acc =
249 new AccessControlContext(new ProtectionDomain[] { domain });
250
251 return acc;
252 }
253 }
254
255 /**
256 * The class loader used for loading from java.class.path.
257 * runs in a restricted security context.
258 */
259 static class AppClassLoader extends URLClassLoader {
260
261 static {
262 ClassLoader.registerAsParallelCapable();
263 }
264
265 public static ClassLoader getAppClassLoader(final ClassLoader extcl)
266 throws IOException
267 {
268 final String s = System.getProperty("java.class.path");
269 final File[] path = (s == null) ? new File[0] : getClassPath(s);
270
271 // Note: on bugid 4256530
272 // Prior implementations of this doPrivileged() block supplied
273 // a rather restrictive ACC via a call to the private method
274 // AppClassLoader.getContext(). This proved overly restrictive
275 // when loading classes. Specifically it prevent
276 // accessClassInPackage.sun.* grants from being honored.
277 //
278 return AccessController.doPrivileged(
279 new PrivilegedAction<AppClassLoader>() {
280 public AppClassLoader run() {
281 URL[] urls =
282 (s == null) ? new URL[0] : pathToURLs(path);
283 return new AppClassLoader(urls, extcl);
284 }
285 });
286 }
287
288 /*
289 * Creates a new AppClassLoader
290 */
291 AppClassLoader(URL[] urls, ClassLoader parent) {
292 super(urls, parent, factory);
293 }
294
295 /**
296 * Override loadClass so we can checkPackageAccess.
297 */
298 public Class loadClass(String name, boolean resolve)
299 throws ClassNotFoundException
300 {
301 int i = name.lastIndexOf('.');
302 if (i != -1) {
303 SecurityManager sm = System.getSecurityManager();
304 if (sm != null) {
305 sm.checkPackageAccess(name.substring(0, i));
306 }
307 }
308 return (super.loadClass(name, resolve));
309 }
310
311 /**
312 * allow any classes loaded from classpath to exit the VM.
313 */
314 protected PermissionCollection getPermissions(CodeSource codesource)
315 {
316 PermissionCollection perms = super.getPermissions(codesource);
317 perms.add(new RuntimePermission("exitVM"));
318 return perms;
319 }
320
321 /**
322 * This class loader supports dynamic additions to the class path
323 * at runtime.
324 *
325 * @see java.lang.instrument.Instrumentation#appendToSystemClassPathSearch
326 */
327 private void appendToClassPathForInstrumentation(String path) {
328 assert(Thread.holdsLock(this));
329
330 // addURL is a no-op if path already contains the URL
331 super.addURL( getFileURL(new File(path)) );
332 }
333
334 /**
335 * create a context that can read any directories (recursively)
336 * mentioned in the class path. In the case of a jar, it has to
337 * be the directory containing the jar, not just the jar, as jar
338 * files might refer to other jar files.
339 */
340
341 private static AccessControlContext getContext(File[] cp)
342 throws java.net.MalformedURLException
343 {
344 PathPermissions perms =
345 new PathPermissions(cp);
346
347 ProtectionDomain domain =
348 new ProtectionDomain(new CodeSource(perms.getCodeBase(),
349 (java.security.cert.Certificate[]) null),
350 perms);
351
352 AccessControlContext acc =
353 new AccessControlContext(new ProtectionDomain[] { domain });
354
355 return acc;
356 }
357 }
358
359 private static class BootClassPathHolder {
360 static final URLClassPath bcp;
361 static {
362 URL[] urls;
363 if (bootClassPath != null) {
364 urls = AccessController.doPrivileged(
365 new PrivilegedAction<URL[]>() {
366 public URL[] run() {
367 File[] classPath = getClassPath(bootClassPath);
368 int len = classPath.length;
369 Set<File> seenDirs = new HashSet<File>();
370 for (int i = 0; i < len; i++) {
371 File curEntry = classPath[i];
372 // Negative test used to properly handle
373 // nonexistent jars on boot class path
374 if (!curEntry.isDirectory()) {
375 curEntry = curEntry.getParentFile();
376 }
377 if (curEntry != null && seenDirs.add(curEntry)) {
378 MetaIndex.registerDirectory(curEntry);
379 }
380 }
381 return pathToURLs(classPath);
382 }
383 }
384 );
385 } else {
386 urls = new URL[0];
387 }
388 bcp = new URLClassPath(urls, factory);
389 }
390 }
391
392 public static URLClassPath getBootstrapClassPath() {
393 return BootClassPathHolder.bcp;
394 }
395
396 private static URL[] pathToURLs(File[] path) {
397 URL[] urls = new URL[path.length];
398 for (int i = 0; i < path.length; i++) {
399 urls[i] = getFileURL(path[i]);
400 }
401 // DEBUG
402 //for (int i = 0; i < urls.length; i++) {
403 // System.out.println("urls[" + i + "] = " + '"' + urls[i] + '"');
404 //}
405 return urls;
406 }
407
408 private static File[] getClassPath(String cp) {
409 File[] path;
410 if (cp != null) {
411 int count = 0, maxCount = 1;
412 int pos = 0, lastPos = 0;
413 // Count the number of separators first
414 while ((pos = cp.indexOf(File.pathSeparator, lastPos)) != -1) {
415 maxCount++;
416 lastPos = pos + 1;
417 }
418 path = new File[maxCount];
419 lastPos = pos = 0;
420 // Now scan for each path component
421 while ((pos = cp.indexOf(File.pathSeparator, lastPos)) != -1) {
422 if (pos - lastPos > 0) {
423 path[count++] = new File(cp.substring(lastPos, pos));
424 } else {
425 // empty path component translates to "."
426 path[count++] = new File(".");
427 }
428 lastPos = pos + 1;
429 }
430 // Make sure we include the last path component
431 if (lastPos < cp.length()) {
432 path[count++] = new File(cp.substring(lastPos));
433 } else {
434 path[count++] = new File(".");
435 }
436 // Trim array to correct size
437 if (count != maxCount) {
438 File[] tmp = new File[count];
439 System.arraycopy(path, 0, tmp, 0, count);
440 path = tmp;
441 }
442 } else {
443 path = new File[0];
444 }
445 // DEBUG
446 //for (int i = 0; i < path.length; i++) {
447 // System.out.println("path[" + i + "] = " + '"' + path[i] + '"');
448 //}
449 return path;
450 }
451
452 private static URLStreamHandler fileHandler;
453
454 static URL getFileURL(File file) {
455 try {
456 file = file.getCanonicalFile();
457 } catch (IOException e) {}
458
459 try {
460 return ParseUtil.fileToEncodedURL(file);
461 } catch (MalformedURLException e) {
462 // Should never happen since we specify the protocol...
463 throw new InternalError();
464 }
465 }
466
467 /*
468 * The stream handler factory for loading system protocol handlers.
469 */
470 private static class Factory implements URLStreamHandlerFactory {
471 private static String PREFIX = "sun.net.www.protocol";
472
473 public URLStreamHandler createURLStreamHandler(String protocol) {
474 String name = PREFIX + "." + protocol + ".Handler";
475 try {
476 Class c = Class.forName(name);
477 return (URLStreamHandler)c.newInstance();
478 } catch (ClassNotFoundException e) {
479 e.printStackTrace();
480 } catch (InstantiationException e) {
481 e.printStackTrace();
482 } catch (IllegalAccessException e) {
483 e.printStackTrace();
484 }
485 throw new InternalError("could not load " + protocol +
486 "system protocol handler");
487 }
488 }
489}
490
491class PathPermissions extends PermissionCollection {
492 // use serialVersionUID from JDK 1.2.2 for interoperability
493 private static final long serialVersionUID = 8133287259134945693L;
494
495 private File path[];
496 private Permissions perms;
497
498 URL codeBase;
499
500 PathPermissions(File path[])
501 {
502 this.path = path;
503 this.perms = null;
504 this.codeBase = null;
505 }
506
507 URL getCodeBase()
508 {
509 return codeBase;
510 }
511
512 public void add(java.security.Permission permission) {
513 throw new SecurityException("attempt to add a permission");
514 }
515
516 private synchronized void init()
517 {
518 if (perms != null)
519 return;
520
521 perms = new Permissions();
522
523 // this is needed to be able to create the classloader itself!
524 perms.add(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);
525
526 // add permission to read any "java.*" property
527 perms.add(new java.util.PropertyPermission("java.*",
528 SecurityConstants.PROPERTY_READ_ACTION));
529
530 AccessController.doPrivileged(new PrivilegedAction<Void>() {
531 public Void run() {
532 for (int i=0; i < path.length; i++) {
533 File f = path[i];
534 String path;
535 try {
536 path = f.getCanonicalPath();
537 } catch (IOException ioe) {
538 path = f.getAbsolutePath();
539 }
540 if (i == 0) {
541 codeBase = Launcher.getFileURL(new File(path));
542 }
543 if (f.isDirectory()) {
544 if (path.endsWith(File.separator)) {
545 perms.add(new FilePermission(path+"-",
546 SecurityConstants.FILE_READ_ACTION));
547 } else {
548 perms.add(new FilePermission(
549 path + File.separator+"-",
550 SecurityConstants.FILE_READ_ACTION));
551 }
552 } else {
553 int endIndex = path.lastIndexOf(File.separatorChar);
554 if (endIndex != -1) {
555 path = path.substring(0, endIndex+1) + "-";
556 perms.add(new FilePermission(path,
557 SecurityConstants.FILE_READ_ACTION));
558 } else {
559 // XXX?
560 }
561 }
562 }
563 return null;
564 }
565 });
566 }
567
568 public boolean implies(java.security.Permission permission) {
569 if (perms == null)
570 init();
571 return perms.implies(permission);
572 }
573
574 public java.util.Enumeration<Permission> elements() {
575 if (perms == null)
576 init();
577 synchronized (perms) {
578 return perms.elements();
579 }
580 }
581
582 public String toString() {
583 if (perms == null)
584 init();
585 return perms.toString();
586 }
587}