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+
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");
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+
491+class 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+}