summaryrefslogtreecommitdiff
path: root/libjava/gnu/gcj/runtime/BootClassLoader.java
blob: 40f3147b7bedd41c40a7943f6ef184057825b059 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* Copyright (C) 2005, 2007  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

package gnu.gcj.runtime;

import gnu.java.net.protocol.core.Handler;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.Vector;

/**
 * This is a helper for the bootstrap class loader.  It is a
 * URLClassLoader so that we can read a class path and re-use all the
 * existing code for finding classes, extracting them from jars, etc.
 * However, it is never called the way that an ordinary ClassLoader is
 * called.  For instance, loadClass() is never used.
 */
public final class BootClassLoader extends HelperClassLoader
{
  // This forces the core URL handler to be included in statically
  // linked executables.  The line that adds core:/ to the search
  // path fails otherwise.
  static Class coreHandler = gnu.java.net.protocol.core.Handler.class;

  private boolean initialized;
  private URLClassLoader bootURLLoader;

  BootClassLoader(String libdir)
  {
    // The BootClassLoader is the top of the delegation chain. It does not
    // have a parent.
    super((ClassLoader) null);
    addDirectoriesFromProperty("java.endorsed.dirs");
    addDirectoriesFromProperty("gnu.gcj.runtime.endorsed.dirs");

    try
      {
	// Add core:/ to the end so any resources compiled into this
	// executable may be found.
	addURL(new URL("core", "", -1, "/"));
      }
    catch (java.net.MalformedURLException x)
      {
	// This should never happen.
	throw new RuntimeException(x);
      }
  }

  public Class bootLoadClass(String name)
    throws ClassNotFoundException
  {
    Class c = findLoadedClass(name);
    if (c == null)
      {
	try
	  {
	    // We could hack URLClassLoader to make this more
	    // efficient, if it mattered.
	    c = findClass(name);
	  }
	catch (ClassNotFoundException _)
	  {
	    c = null;
	  }
      }
    return c;
  }

  // Parse the boot classpath and create a URLClassLoader that loads
  // resources from it.  This is provided for the benefit of code that
  // does things like
  //   ClassLoader.getResourceAsStream("java/lang/Object.class")
  private synchronized URLClassLoader getBootURLLoader()
  {
    if (initialized)
      return bootURLLoader;
    initialized = true;

    Vector<URL> urls = new Vector<URL>();
    String bootClasspath = System.getProperty ("sun.boot.class.path");
    StringTokenizer st =
      new StringTokenizer(bootClasspath, File.pathSeparator);
    while (st.hasMoreTokens())
      {
	try
	  {
	    urls.add(new File(st.nextToken()).toURL());
	  }
	catch (java.net.MalformedURLException e)
	  {
	  }
      }

    if (urls.size() > 0)
      bootURLLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]));
    return bootURLLoader;
  }

  public URL bootGetResource(String name)
  {
    URL url = findResource(name);
    if (url != null)
      return url;

    URLClassLoader loader = getBootURLLoader();
    if (loader != null)
      url = loader.findResource(name);

    return url;
  }

  public Enumeration bootGetResources(String name) throws IOException
  {
    URLClassLoader loader = getBootURLLoader();
    Enumeration[] e =
      {
	findResources(name),
	(loader != null) ? loader.findResources(name) : null
      };

    Vector v = new Vector();
    for (Enumeration en : e)
      if (en != null)
	while (en.hasMoreElements())
	  v.add(en.nextElement());

    return v.elements();
  }
}