Complete AppLauncher for Java

Hi!
I’m looking forward to build a simple Application Launcher that can be given any .jar to launch it with selected options. Games often need to have the heap memory initialized at a certain amount of RAM, as well as the permissions must be set up to the correct values.
Therefore I have an unique class that launch itself from the command line or the Operating system file browser. It is named AppLauncher with a common static main method that looks like the code follows:

/***/
    public static void main(String[] args) {
        String xms, xmx, codecsDisabled, openGL, ddscale, translaccel, ddforcevram, cwd;
        System.out.println(System.getProperties());
        xms = "64M";
        xmx = "1024M";
        codecsDisabled = "false";
        openGL = "True";
        translaccel = "true";
        ddscale = "true";
        ddforcevram = "true";
        cwd = ".";
        new UIMessage("AppLauncher will ask you to select the .jar to launch.", null);
        FileChooserPane fcp = new FileChooserPane(null, ".");
        HashSet ext = new HashSet();
        ext.add("jar");
        fcp.addFileFilter(ext);
        fcp.setMultiSelectionEnabled(false);
        fcp.setModeOpen(true);
        File[] f = fcp.getFile();
        new UIMessage("AppLauncher will ask you to select the policy file to use if available, or simply tap cancel.", null);
        fcp.setMultiSelectionEnabled(false);
        fcp.setModeOpen(true);
        File[] policy = fcp.getFile();
        if(f == null)
            return;
        else if(f[0] == null)
            return;
        JFrame frame = UIMessage.displayWaiting("Loading...", null);
        Process p = null;
        String command = "";
        Runtime.getRuntime().traceInstructions(true);
        try {if(System.getProperty("os.arch").equals("x86")) {
            args = new String[]{
                "-jar \"" + f[0].getCanonicalPath() + "\"",
                (policy != null)?"-Djava.security.policy=\"" + policy[0].getCanonicalPath() + "\"":"",
                "-Xms" + xms,
                "-Xmx" + xmx,
                "-Dcom.sun.media.imageio.disableCodecLib=" + codecsDisabled,
                "-Dsun.java2d.opengl=" + openGL,
                "-Dsun.java2d.ddscale=" + ddscale,
                "-Dsun.java2d.translaccel=" + translaccel,
                "-Dsun.java2d.ddforcevram=" + ddforcevram
            };
            command = "java";
        } else if(System.getProperty("os.arch").equals("ppc")) {
            args = new String[]{
                "-jar \"" + f[0].getCanonicalPath() + "\"",
                (policy != null)?"-Djava.security.policy=\"" + policy[0].getCanonicalPath() + "\"":"",
                "-Xms" + xms,
                "-Xmx" + xmx,
                "-Dcom.sun.media.imageio.disableCodecLib=" + codecsDisabled,
                "-Dsun.java2d.opengl=" + openGL,
                "-Dsun.java2d.translaccel=" + translaccel
            };
            command = "java";
        } else
            new UIMessage(System.getProperty("os.arch") + " architectures are currently not supported. Program is going to exit...", null);
        String argss = "";
        for(String arg : args)
            argss += arg + " ";
        new UIMessage("LAUNCH : " + command + " " + argss, null);
        p = Runtime.getRuntime().exec(command, args,
                new File(cwd)
                );
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if(p instanceof Process) {
                final Console console = new Console();
                final BufferedInputStream err = new BufferedInputStream(p.getErrorStream());
                Thread t = new Thread(new Runnable() { public void run(){
                    try{
                        Map<String, Object> map = console.newPrintStream(new ErrorListener() {
                            public void printStreamError(IOException e) {
                                e.printStackTrace();
                            }
                        });
                        PrintStream ps = ((PrintStream)map.get("ps"));
                        byte[] s = new byte[128];
                        while(err.read(s) != -1)
                            ps.append(new String(s));
                    } catch(IOException e) {
                        e.printStackTrace();
                    }
                }}, "T-App Launcher ErrorLog");
                t.setPriority(Thread.MAX_PRIORITY);
                t.start();
                console.sendConsoleEvent(Console.PRINT_RESUME);
                frame.dispose();
                try {
                    p.waitFor();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
            System.exit(0);
        }

But this doesn’t fill its purpose at all. it terminates with System.exit(0) and the java command is left uncompleted. Plus I can’t find out the possible exception thrown, where is the problem? I can agree that the command Runtime.getRuntime().exec() seems terribly tiny but I cannot find a different manner, can I? ??? ??? ??? ??? ???

For windows at least, I’ve had a lot of luck using NSIS for some nice polished launchers.

As an added bonus, from the fact it’s an “installer”… it can do things like hunt around for the proper java runtime (Very helpful if env. variables aren’t set up right)… ensure any libraries you need are present (install them from itself if not found)

thanks but that might be helpful to have it for my own. Any other ideas?

Code’s been modified as follows; the command args were misplaced on the method call exec(command, envp). args were told as enironment params, which was wrong. But now the problem still occur as the command terminates and I get Java axit status 1 all the time, why?
???

/***/
    public static void main(String[] args) {
        String xms, xmx, codecsDisabled, openGL, ddscale, translaccel, ddforcevram, cwd;
        System.out.println(System.getProperties());
        xms = "64M";
        xmx = "1024M";
        codecsDisabled = "false";
        openGL = "True";
        translaccel = "true";
        ddscale = "true";
        ddforcevram = "true";
        cwd = ".";
        new UIMessage("AppLauncher will first ask you to find the java binary installed on your HDD.", null);
        FileChooserPane fcp = new FileChooserPane(null, System.getProperty("java.home"));
        File[] fcmd = fcp.getFile();
        if(fcmd == null)
            return;
        HashSet ext = new HashSet();
        ext.add("jar");
        fcp.addFileFilter(ext);
        fcp.setMultiSelectionEnabled(false);
        fcp.setModeOpen(true);
        new UIMessage("AppLauncher will ask you to select the .jar to launch.", null);
        File[] f = fcp.getFile();
        new UIMessage("AppLauncher will ask you to select the policy file to use if available, or simply tap cancel.", null);
        fcp.setMultiSelectionEnabled(false);
        fcp.setModeOpen(true);
        File[] policy = fcp.getFile();
        if(f == null)
            return;
        else if(f[0] == null)
            return;
        JFrame frame = UIMessage.displayWaiting("Loading...", null);
        Process p = null;
        String[] command = new String[]{""};
        String commandline = "";
        Runtime.getRuntime().traceInstructions(true);
        try {
            if(System.getProperty("os.arch").equals("x86")) {
                args = new String[]{
                    "-Xms" + xms,
                    "-Xmx" + xmx,
                    "-Dcom.sun.media.imageio.disableCodecLib=" + codecsDisabled,
                    "-Dsun.java2d.opengl=" + openGL,
                    "-Dsun.java2d.ddscale=" + ddscale,
                    "-Dsun.java2d.translaccel=" + translaccel,
                    "-Dsun.java2d.ddforcevram=" + ddforcevram
                };
                command = new String[]{
                    fcmd[0].getAbsolutePath(),
                    (policy != null)?"-Djava.security.policy=\"" + policy[0].getCanonicalPath() + "\"":"",
                    "-jar \"" + f[0].getCanonicalPath() + "\""
                };
            } else if(System.getProperty("os.arch").equals("ppc")) {
                args = new String[]{
                    "-Xms" + xms,
                    "-Xmx" + xmx,
                    "-Dcom.sun.media.imageio.disableCodecLib=" + codecsDisabled,
                    "-Dsun.java2d.opengl=" + openGL,
                    "-Dsun.java2d.translaccel=" + translaccel
                };
                command = new String[]{
                    fcmd[0].getAbsolutePath(),
                    (policy != null)?"-Djava.security.policy=\"" + policy[0].getCanonicalPath() + "\"":"",
                    "-jar \"" + f[0].getCanonicalPath() + "\""
                };
            } else
                new UIMessage(System.getProperty("os.arch") + " architectures are currently not supported. Program is going to exit...", null);
            String argss = "";
            for(String arg : args)
                argss += arg + " ";
            for(String s : command)
                commandline += s + " ";
            String msg = "LAUNCH : " + commandline + " ; w/ environment params: " + argss;
            System.out.println(msg);
            JTextField cmd = new JTextField(msg);
            cmd.setEditable(false);
            cmd.setDragEnabled(true);
            new UIMessage(cmd, null);
            p = Runtime.getRuntime().exec(command, args
                    );
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if(p instanceof Process) {
                final Console console = new Console();
                final BufferedInputStream err = new BufferedInputStream(p.getErrorStream());
                final BufferedInputStream in = new BufferedInputStream(p.getInputStream());
                try{
                    Thread t_err = console.getNewInput(err);
                    Thread t_in = console.getNewInput(in);
                    t_err.start();
                    t_in.start();
                } catch(IOException e) {
                    e.printStackTrace();
                } finally {
                    frame.dispose();
                    try {
                        p.waitFor();
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
            }
            new UIMessage(commandline + " has exited with status " + p.exitValue() + " (0 for normal termination)", null);
        }
    }

I want ot launch other java application from my Applet, how is this possible? this the command I pass to the (Runtime).exec :


LAUNCH : Runtime.getRuntime().exec("/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Commands/java -Djava.security.policy=\"/Users/website/AnimationDemo3/dist/JavaSecurityPolicy\" -jar \"/Users/website/Desktop/KeyFileIO_Ant-ppc_signed.jar\",
"-Xms64M -Xmx1024M -Dcom.sun.media.imageio.disableCodecLib=false -Dsun.java2d.opengl=True -Dsun.java2d.translaccel=true"); 

But java exits with status errored 1… both with Windows (I also have got the java.exe home directory for windows) and OS X Does someone can help?

I got help from these forums developing something similar that you might be able to use:

http://www.java-gaming.org/forums/index.php?topic=16231.msg128426#msg128426

Keith

Thx but this doesn’t work better… And after testing the Applet linked to your post I m unable to testify that the JVM is really relaunched as it is told in previous posts. The applet simply perform the code exec throughout the Java Reflection API, doesnt it?
I looked at the ProcessBuilder Tutorial at sun.com, where it is told to open a RuntimePermission on getenv.*, but the problem still is that I can’t get the Java bin running. For sure the java bin works with the given .jar I want to launch from the AppLauncher when I test it on the BeanShell command line.
Plus I can’t get the error thrown by the Process task, that’s another issue to solve. I did manage to see the error in the past, which I can’t get it working anymore… That’s so fuzzy!!
Any other exps? ???

P.S : the AppLauncher is available for beta-testing (for the reasons above) in my “java webstart pool” Applauncher.jnlp

:o :o :oSolution is that one to make a script file and to launch it with the environment params trough exec(). The reason is that (Runtime).exec() doesn’t support some native applications to load through its processBuidler. ;D

/***/
    public static void main(String[] args) {
        _load();
        Process p = null;
        String shell = "";
        String shellFile = "";
        String commandline = "";
        String cwd = "";
        String[] pargs = new String[]{};
        String xms, xmx, codecsDisabled, openGL, ddscale, translaccel, ddforcevram;
        System.out.println(System.getProperties());
        xms = "64M";
        xmx = "1024M";
        codecsDisabled = "false";
        openGL = "True";
        translaccel = "true";
        ddscale = "true";
        ddforcevram = "true";
        new UIMessage("AppLauncher will first ask you to find the java binary installed on your HDD.", null);
        FileChooserPane fcp = new FileChooserPane(null, System.getProperty("java.home"));
        File[] fcmd = fcp.getFile();
        if(fcmd == null){
            if(JOptionPane.showConfirmDialog(null, new JLabel("Do I relaunch the app' ?"), "relaunch ?", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
                main(args);
            else
                exit(0);
        }
        HashSet ext = new HashSet();
        ext.add("jar");
        fcp.addFileFilter(ext);
        fcp.setMultiSelectionEnabled(false);
        fcp.setModeOpen(true);
        new UIMessage("AppLauncher will ask you to select the .jar to launch.", null);
        fcp.clearAllFileFilters();
        File[] f = fcp.getFile();
        new UIMessage("AppLauncher will ask you to select the policy file to use if available, or simply tap cancel.", null);
        fcp.setMultiSelectionEnabled(false);
        fcp.setModeOpen(true);
        File[] policy = fcp.getFile();
        if(f == null) {
            if(JOptionPane.showConfirmDialog(null, new JLabel("Do I relaunch the app' ?"), "relaunch ?", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
                main(args);
            else
                exit(0);
        } else if(f[0] == null) {
            if(JOptionPane.showConfirmDialog(null, new JLabel("Do I relaunch the app' ?"), "relaunch ?", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
                main(args);
            else
                exit(0);
        }
        JFrame frame = UIMessage.displayWaiting("Loading...", null);
        Thread t;
        Console console = new Console();
        String[] command = new String[]{""};
        try {
            if(System.getProperty("os.arch").equals("x86")) {
                shellFile = "run.bat";
                shell = new File(shellFile).getAbsolutePath();
                pargs = new String[]{
                    "-Xms" + xms,
                    "-Xmx" + xmx,
                    "-Dcom.sun.media.imageio.disableCodecLib=" + codecsDisabled,
                    "-Dsun.java2d.opengl=" + openGL,
                    "-Dsun.java2d.ddscale=" + ddscale,
                    "-Dsun.java2d.translaccel=" + translaccel,
                    "-Dsun.java2d.ddforcevram=" + ddforcevram
                };
                command = new String[]{
                    "\"" + fcmd[0].getAbsolutePath() + "\"",
                    (policy != null)?"-Djava.security.policy=\"" + policy[0].getCanonicalPath() + "\"":"",
                    "-jar \"" + f[0].getCanonicalPath() + "\""
                };
            } else if(System.getProperty("os.arch").equals("ppc")) {
                shellFile = ".run";
                shell = "/bin/sh " + new File(shellFile).getAbsolutePath();
                pargs = new String[]{
                    "-Xms" + xms,
                    "-Xmx" + xmx,
                    "-Dcom.sun.media.imageio.disableCodecLib=" + codecsDisabled,
                    "-Dsun.java2d.opengl=" + openGL,
                    "-Dsun.java2d.translaccel=" + translaccel
                };
                command = new String[]{
                    "\"" + fcmd[0].getAbsolutePath() + "\"",
                    (policy != null)?"-Djava.security.policy=\"" + policy[0].getCanonicalPath() + "\"":"",
                    "-jar \"" + f[0].getCanonicalPath() + "\""
                };
            } else
                new UIMessage(System.getProperty("os.arch") + " architectures are currently not supported. Program is going to exit...", null);
            cwd = f[0].getParentFile().getAbsolutePath();
            String argss = "";
            Vector<String> cmdList = new Vector<String>();
            for(String s : command) {
                commandline += s + " ";
                cmdList.add(s);
            }
            for(String arg : pargs) {
                argss += arg + " ";
                cmdList.add(arg);
            }
            String msg = "LAUNCH : " + commandline + " ; w/ environment params : " + argss + " and working directory : " + cwd;
            System.out.println(msg);
            File runFile = new File(shellFile);
            runFile.deleteOnExit();
            RandomAccessFile raf = new RandomAccessFile(runFile, "rws");
            raf.write(commandline.getBytes());
            raf.close();
            new UIMessage(msg, null);
            p = Runtime.getRuntime().exec(shell, pargs, new File(cwd));
            console.setOutput(System.out);
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if(p instanceof Process) {
                try{
                    Thread t_err = console.getNewInput(p.getErrorStream());
                    Thread t_in = console.getNewInput(p.getInputStream());
                    t_err.start();
                    t_in.start();
                } catch(IOException e) {
                    e.printStackTrace();
                } finally {
                    frame.dispose();
                    try {
                        p.waitFor();
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    } finally {
                        new UIMessage(commandline + " has exited with status " + p.exitValue() + " (0 for normal termination)", null);
                    }
                }
            }
            if(JOptionPane.showConfirmDialog(null, new JLabel("Do I relaunch the app' ?"), "relaunch ?", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
                main(args);
            else
                exit(0);
        }
    }
    
    /***/
    public static boolean _exitOnMain = true;
    /***/
    private static void exit(int i) {
        if(_exitOnMain)
            System.exit(i);
    }