All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ity.jettyconsole.jetty-console-core.1.44.source-code.JettyConsoleBootstrapMainClass Maven / Gradle / Ivy

There is a newer version: 1.61
Show newest version
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

/**
 * The purpose of this class is to be the Main-Class of a JAR file.
 * On startup, the class will extract the "real" application by extracing the jar files
 * in /META-INF/jettyconsole/lib into a temporary directory, setting up a class loader
 * and executing the {@link org.simplericity.jettyconsole.JettyConsoleStarter}'s main method.
 *
 * On shutdown, this class will remove the temporatily extracted jar files.
 */
public class JettyConsoleBootstrapMainClass implements Runnable {

    private static JettyConsoleBootstrapMainClass instance;
    private ClassLoader cl;
    private Runnable shutdown;

    public static void start(String[] arguments) throws Exception {
        System.out.println("JettyConsole Windows Service starting");
        instance = new JettyConsoleBootstrapMainClass();
        instance.setupWindowsService();
        instance.run(arguments);
        synchronized (instance) {
            instance.wait();
        }
        instance.shutdown.run();
        System.out.println("JettyConsole Windows Service main thread exiting");
    }

    private void setupWindowsService() {
        File tempDirectory = new File(".", "temp");
        System.setProperty("java.io.tmpdir", tempDirectory.getAbsolutePath());
        tempDirectory.mkdirs();
        for(File child : tempDirectory.listFiles()) {
            delete(child);
        }
    }

    private void delete(File file) {
        if(file.isDirectory()) {
            for(File child : file.listFiles()) {
                delete(child);
            }
        }
        file.delete();
    }

    public static void stop(String[] args) {
        System.out.println("JettyConsole Windows Service stopping");
        synchronized (instance) {
            instance.notifyAll();
        }
    }


    /**
     * Create an instance of Main and invoke the {@link JettyConsoleBootstrapMainClass#run()} method.
     * @param arguments
     * @throws Exception
     */
    public static void main(String[] arguments) throws Exception {
        new JettyConsoleBootstrapMainClass().run(arguments);
    }

    /**
     * Extract jar files, set up a class loader and execute {@link org.simplericity.jettyconsole.JettyConsoleStarter}'s main method.
     * @param arguments
     * @throws Exception
     */
    private void run(String[] arguments) throws Exception {

            checkTemporaryDirectory(arguments);


            addShutdownHook();

            File war = getWarLocation();

            cl = createClassLoader(war);

            Thread.currentThread().setContextClassLoader(cl);

            startJettyConsole(cl, arguments);
    }

    private void checkTemporaryDirectory(String[] arguments) {
        for (int i = 0; i < arguments.length; i++) {
            String argument = arguments[i];
            if("--tmpDir".equals(argument)) {
                if(i == arguments.length -1) {
                    System.err.println("--tmpDir must take a path as an argument" );
                } else {
                    File tmpDir = new File(arguments[i+1]);
                    if(!tmpDir.exists()) {
                        err("tmpDir does not exist: " + tmpDir);
                    } else if(!tmpDir.isDirectory()) {
                        err("tmpDir is not a directory: " + tmpDir);
                    } else {
                        System.setProperty("java.io.tmpdir", tmpDir.getAbsolutePath());
                    }

                }
            }
        }
    }

    private void err(String msg) {
        System.err.println();
        System.err.println("ERROR: " +msg);
        System.exit(0);
    }

    /**
     * Load {@link org.simplericity.jettyconsole.JettyConsoleStarter} and execute its main method.
     * @param cl The class loader to use for loading {@link org.simplericity.jettyconsole.JettyConsoleStarter}
     * @param arguments the arguments to pass to the main method
     */
    private void startJettyConsole(ClassLoader cl, String[] arguments) {
        try {
            Class starterClass = cl.loadClass("org.simplericity.jettyconsole.JettyConsoleStarter");
            Method main = starterClass.getMethod("main", arguments.getClass());
            main.invoke(null, new Object[] {arguments});
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }

    private void stopJettyConsole(ClassLoader cl) {
        try {
            Class starterClass = cl.loadClass("org.simplericity.jettyconsole.JettyConsoleStarter");
            Method main = starterClass.getMethod("stop");
            main.invoke(null);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Create a URL class loader containing all jar files in the given directory
     * @param warFile the waf file to look for libs dirs in
     * @return
     */
    private ClassLoader createClassLoader(File warFile) {
        try {
            List urls = new ArrayList();

            URL mainResource = getClass().getClassLoader().getResource(getClass().getName().replace('.', '/') + ".class");
            JarInputStream in = new JarInputStream(new FileInputStream(warFile));

            while(true) {
                JarEntry entry = in.getNextJarEntry();
                if(entry == null) {
                    break;
                }
                String name = entry.getName();
                String prefix = "META-INF/jettyconsole/lib/";
                if(entry.isDirectory() && name.startsWith(prefix) ) {
                    int slash = name.indexOf("/", prefix.length());
                    if(slash >0) {
                        String simpleName = name.substring(prefix.length(), slash);
                        if (name.equals(prefix + simpleName + "/")) {
                            urls.add(new URL(mainResource, name));
                        }
                    }

                }
            }
            in.close();
            return new URLClassLoader(urls.toArray(new URL[urls.size()]), JettyConsoleBootstrapMainClass.class.getClassLoader());

        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void addShutdownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread(shutdown = this));
    }

    /**
     * Delete the temporary directory on shutdown.
     */
    public void run() {
        stopJettyConsole(cl);
    }

    /**
     * Return a File pointing to the location of the Jar file this Main method is executed from.
     * @return
     */
    public File getWarLocation() {
        URL resource = JettyConsoleBootstrapMainClass.class.getResource("/WEB-INF/web.xml");
        String file = resource.getFile();
        file = file.substring("file:".length(), file.indexOf("!"));
        try {
            file = URLDecoder.decode(file, "utf-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        return new File(file);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy