Package

Source Code of Bootstrapper

import javax.xml.bind.DatatypeConverter;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.util.LinkedList;
import java.util.List;

/**
* Launches an embedded Jar file from within a script.
*
* @author Robert Wapshott
*/
public class Bootstrapper {

    public static final String SIGNAL = Bootstrapper.class.getSimpleName();
    private static List<String> buffer = new LinkedList<String>();

    public static void main(String[] args) {
        if (args.length < 1) throw new IllegalStateException("missing Jar argument");

        try {
            String path = args[0];
            log("Reading: " + path);

            InputStream stream = locateStream(path);
            byte[] data = extractJar(stream);
            File jar = writeJar(data);
            log("Extracted (" + String.valueOf(jar.length()) + " bytes) to " + jar.getPath());

            log("Executing...");
            String[] jarArgs = new String[args.length - 1];
            System.arraycopy(args, 1, jarArgs, 0, args.length - 1);
            int result = launchJar(jar, jarArgs);
            log("Completed: " + String.valueOf(result));

            if (jar.delete()) {
                log("Deleted jar");
            }

            System.exit(result);
        } catch (Throwable e) {
            System.err.println(e.getMessage());
            for (String line : buffer) {
                System.err.println(line);
            }
        }
    }

    /**
     * Locate the SIGNAL line in a given file and return the input stream that corresponds to
     * the location after that line.
     */
    public static InputStream locateStream(String path) throws IOException {
        // Locate the signal
        RandomAccessFile raf = new RandomAccessFile(path, "r");
        while (!raf.readLine().equals(SIGNAL));
        long total = raf.getFilePointer();
        raf.close();
        // Seek in the stream
        InputStream in = new BufferedInputStream(new FileInputStream(path));
        while (total != 0) {
            long skipped = in.skip(total);
            if (skipped > 0) {
                total -= skipped;
            }
        }
        return in;
    }

    /**
     * Extract the contents of a stream to a byte array and decode contents.
     */
    public static byte[] extractJar(InputStream in) throws IOException {
        ByteArrayOutputStream dout = new ByteArrayOutputStream();
        OutputStream out = new BufferedOutputStream(dout);
        copyStream(in, out);

        String data = new String(dout.toByteArray());
        byte[] bytes = DatatypeConverter.parseBase64Binary(data);

        return bytes;
    }

    /**
     * Write the data to a Jar.
     */
    public static File writeJar(byte[] data) throws IOException {
        File jar = File.createTempFile("launcher", ".jar");
        ByteArrayInputStream in = new ByteArrayInputStream(data);
        OutputStream out = new BufferedOutputStream(new FileOutputStream(jar));
        copyStream(in, out);
        return jar;
    }

    /**
     * Launch a jar file with the forwarded arguments and prints the output.
     */
    public static int launchJar(File jar, String[] jarArgs) throws IOException, InterruptedException {
        String cmd = "java -jar " + jar.getAbsolutePath();
        // The forwarded arguments.
        if (jarArgs.length > 0) {
            cmd += " ";
            for (String arg : jarArgs) {
                cmd += arg + " ";
            }
            cmd = cmd.substring(0, cmd.length() - " ".length());
        }

        final Process result = Runtime.getRuntime().exec(cmd);
        new Thread(new Runnable(){
            @Override
            public void run() {
                new Printer(result.getInputStream(), System.out);
            }
        }).start();
        new Thread(new Runnable(){
            @Override
            public void run() {
                new Printer(result.getErrorStream(), System.err);
            }
        }).start();
        return result.waitFor();
    }

    /**
     * Writes the input to the output.
     */
    private static class Printer {

        private static final String NL = System.getProperty("line.separator");
        public Printer(InputStream in, PrintStream out) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            PrintWriter writer = new PrintWriter(out);
            String data;
            try {
                while ((data = reader.readLine()) != null) {
                    writer.write(data + NL);
                    writer.flush();
                }
                in.close();
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
        }

    }

    private static long start;
    private static void time() {
        start = System.currentTimeMillis();
    }

    private static void timeEnd(String msg) {
        long diff = System.currentTimeMillis() - start;
        log("--- " + diff + "ms:\t" + msg);
    }

    private static void log(String message) {
        buffer.add(message);
    }

    private static void copyStream(InputStream in, OutputStream out) {
        byte[] buf = new byte[100000];
        int read;
        try {
            while ((read = in.read(buf)) != -1) {
                out.write(buf, 0, read);
            }
            out.flush();
            out.close();
            in.close();
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }
}
TOP

Related Classes of Bootstrapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.