aboutsummaryrefslogblamecommitdiff
path: root/nailgun_launcher/NailgunLauncher.java
blob: cd9e499e11f1762b237537c46272c767e20d89ad (plain) (tree)
1
2
3
4
5
6
7
8
9








                                              
   
                                                                                           



                                                                                     

                                               
                             
 
     
                                                                                                   
                                  
     

                                                                                                                            
 

                                                                                     


                                                                       

                                                                          














                                                                                                             
                                                                                                      




                                                                                                
                                                         






                                                          
                                                             








                                                                 
     
 
                                        



                                                   




                                                               


   
                                               
                           













                                                              
   
 
package cbt;
import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.nio.*;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * This launcher allows to start the JVM without loading anything else permanently into its
 * classpath except for the launcher itself. That's why it is written in Java without
 * dependencies outside the JDK.
 *
 * The main method loads the given class from the given class path, calls it's main
 * methods passing in the additional arguments.
 */
public class NailgunLauncher{

  /**
   * Persistent cache for caching classloaders for the JVM life time. Can be used as needed by user
   * code to improve startup time.
   */
  public static ConcurrentHashMap<String, Object> classLoaderCacheKeys = new ConcurrentHashMap<String,Object>();
  public static ConcurrentHashMap<Object, ClassLoader> classLoaderCacheValues = new ConcurrentHashMap<Object,ClassLoader>();

  public static SecurityManager defaultSecurityManager = System.getSecurityManager();

  public static void main(String[] args) throws ClassNotFoundException,
                                                NoSuchMethodException,
                                                IllegalAccessException,
                                                InvocationTargetException,
                                                MalformedURLException {
    String CBT_HOME = System.getenv("CBT_HOME");
    String SCALA_VERSION = System.getenv("SCALA_VERSION");
    String NAILGUN = System.getenv("NAILGUN");
    String STAGE1 = System.getenv("STAGE1");
    String TARGET = System.getenv("TARGET");
    assert(CBT_HOME != null);
    assert(SCALA_VERSION != null);
    assert(NAILGUN != null);
    assert(STAGE1 != null);
    assert(TARGET != null);

    String library = CBT_HOME+"/bootstrap_scala/cache/"+SCALA_VERSION+"/scala-library-"+SCALA_VERSION+".jar";
    if(!classLoaderCacheKeys.containsKey(library)){
      Object libraryKey = new Object();
      classLoaderCacheKeys.put(library,libraryKey);
      ClassLoader libraryClassLoader = new CbtURLClassLoader( new URL[]{ new URL("file:"+library) } );
      classLoaderCacheValues.put(libraryKey, libraryClassLoader);

      String xml = CBT_HOME+"/bootstrap_scala/cache/"+SCALA_VERSION+"/scala-xml_2.11-1.0.5.jar";
      Object xmlKey = new Object();
      classLoaderCacheKeys.put(xml,xmlKey);
      ClassLoader xmlClassLoader = new CbtURLClassLoader(
        new URL[]{ new URL("file:"+xml) },
        libraryClassLoader
      );
      classLoaderCacheValues.put(xmlKey, xmlClassLoader);

      Object nailgunKey = new Object();
      classLoaderCacheKeys.put(NAILGUN+TARGET,nailgunKey);
      ClassLoader nailgunClassLoader = new CbtURLClassLoader(
        new URL[]{ new URL("file:"+NAILGUN+TARGET) },
        xmlClassLoader
      );
      classLoaderCacheValues.put(nailgunKey, nailgunClassLoader);
    }

    if(args[0].equals("check-alive")){
      System.exit(33);
      return;
    }

    ClassLoader cl = new URLClassLoader(
      new URL[]{ new URL("file:"+STAGE1+TARGET) }, 
      classLoaderCacheValues.get(
        classLoaderCacheKeys.get( NAILGUN+TARGET )
      )
    );

    cl.loadClass("cbt.Stage1")
      .getMethod("main", String[].class, ClassLoader.class)
      .invoke( null/* _cls.newInstance()*/, (Object) args, cl);
  }
}

class CbtURLClassLoader extends URLClassLoader{
  public String toString(){
    return (
      super.toString()
      + "(\n  "
      + Arrays.toString(getURLs())
      + ",\n  "
      + String.join("\n  ",getParent().toString().split("\n"))
      + "\n)"
    );
  }
  public CbtURLClassLoader(URL[] urls, ClassLoader parent){
    super(urls, parent);
  }
  public CbtURLClassLoader(URL[] urls){
    super(urls);
  }
}