001/*
002 *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 *  This file is licensed to You under the Eclipse Public License (EPL);
005 *  You may not use this file except in compliance with the License. You
006 *  may obtain a copy of the License at
007 *
008 *      http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 *  See the COPYRIGHT.txt file distributed with this work for information
011 *  regarding copyright ownership.
012 */
013package org.jikesrvm.classloader;
014
015import java.io.File;
016import java.net.MalformedURLException;
017import java.net.URL;
018import java.net.URLClassLoader;
019import java.util.StringTokenizer;
020
021import org.jikesrvm.VM;
022import org.jikesrvm.runtime.Magic;
023import org.jikesrvm.util.Services;
024
025/**
026 * The class loader used by Jikes RVM to load the application program.  Since
027 * version 1.2 of the Sun API docs, the Application ClassLoader  and the
028 * System Class Loader are officially the same thing.  (What Jikes RVM used to
029 * call the "System Class Loader" is officially the "Bootstrap Class
030 * Loader".)
031 * <p>
032 * We use a two-link chain.  An ordinary user's class is loaded by this class
033 * loader.  This class loader first delegates to its parent (the Bootstrap
034 * Class Loader) before trying the class itself.
035 * <p>
036 *  Renamed the former "system class loader" to the "bootstrap class loader".
037 */
038public class ApplicationClassLoader extends URLClassLoader {
039
040  static final boolean DBG = false;
041
042  static int numInstantiations = 0;
043
044  /** For status printing, to make sure that, if an application class loader is
045   *  created at boot image writing time, it won't leak out into the next
046   *  mode.   This is actually not used any more, but it should never hurt,
047   *  and can give one a sense of confidence when debugging Jikes RVM's
048   *  classloaders.
049   *  */
050  private final boolean createdAtBootImageWritingTime;
051  private final boolean createdWithRunningVM;
052
053  public ApplicationClassLoader(String specifiedClasspath) {
054    super(new URL[0]);
055    if (DBG) {
056      VM.sysWriteln("The Application Class Loader has been instantiated ", numInstantiations, " times");
057    }
058    ++numInstantiations;
059
060    createdAtBootImageWritingTime = VM.writingBootImage;
061    createdWithRunningVM = VM.runningVM;
062
063    try {
064      if (specifiedClasspath == null) {
065        addURL(new URL("file", null, -1, System.getProperty("user.dir") + File.separator));
066      } else {
067        StringTokenizer tok = new StringTokenizer(specifiedClasspath, File.pathSeparator);
068        while (tok.hasMoreElements()) {
069          String elt = tok.nextToken();
070
071          if (!(elt.endsWith(".jar") || elt.endsWith(".zip"))) {
072            if (!elt.endsWith(File.separator)) {
073              elt += File.separator;
074            }
075          }
076
077          if (elt.indexOf(File.pathSeparatorChar) != -1) {
078            addURL(new URL(elt));
079          } else if (elt.startsWith(File.separator)) {
080            addURL(new URL("file", null, -1, elt));
081          } else {
082            addURL(new URL("file", null, -1, System.getProperty("user.dir") + File.separator + elt));
083          }
084        }
085      }
086    } catch (MalformedURLException e) {
087      VM.sysFail(
088          "JikesRVM: ApplicationClassLoader: Initialization Failed with a MalformedURLException; there was an error setting the application's classpath: " +
089          e);
090    }
091  }
092
093  /** Name of the Application Class Loader.  Actually used by Jikes RVM's
094   * serialization code.
095   * <P>
096   * I intended this name to reflect both "SystemClassLoader" and
097   * "ApplicationClassLoader".
098   */
099  public static final String myName = "SystemAppCL";
100
101  @Override
102  public String toString() {
103    return myName +
104           (createdAtBootImageWritingTime ? "-createdAtBootImageWritingTime" : "") +
105           (createdWithRunningVM ? "" : "-NOTcreatedWithRunningVM") +
106           (DBG ? "@" + Services.addressAsHexString(Magic.objectAsAddress(this)) : "");
107  }
108
109  @Override
110  protected String findLibrary(String libName) {
111    return null;
112  }
113}
114
115