org.exist.launcher.LauncherWrapper.java Source code

Java tutorial

Introduction

Here is the source code for org.exist.launcher.LauncherWrapper.java

Source

/*
 *  eXist Open Source Native XML Database
 *  Copyright (C) 2012 The eXist Project
 *  http://exist-db.org
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  $Id$
 */
package org.exist.launcher;

import org.apache.commons.configuration2.PropertiesConfiguration;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.lang3.SystemUtils;
import org.exist.util.ConfigurationHelper;
import org.rzo.yajsw.os.OperatingSystem;
import org.rzo.yajsw.os.Process;
import org.rzo.yajsw.os.ProcessManager;
import org.rzo.yajsw.os.ms.win.w32.WindowsXPProcess;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * A wrapper to start a Java process using start.jar with correct VM settings.
 * Spawns a new Java VM using Ant. Mainly used when launching
 * eXist by double clicking on start.jar.
 *
 * @author Tobi Krebs
 * @author Wolfgang Meier
 */
public class LauncherWrapper {

    private final static String LAUNCHER = org.exist.launcher.Launcher.class.getName();
    private final static String OS = System.getProperty("os.name").toLowerCase();

    public final static void main(String[] args) {
        final LauncherWrapper wrapper = new LauncherWrapper(LAUNCHER);
        if (ConfigurationUtility.isFirstStart()) {
            System.out.println("First launch: opening configuration dialog");
            ConfigurationDialog configDialog = new ConfigurationDialog(restart -> {
                wrapper.launch();
            });
            configDialog.open(true);
            configDialog.requestFocus();
        } else {
            wrapper.launch();
        }
    }

    protected String command;

    public LauncherWrapper(String command) {
        this.command = command;
    }

    public void launch() {
        final String home = System.getProperty("exist.home", ".");
        final String debugLauncher = System.getProperty("exist.debug.launcher", "false");
        final PropertiesConfiguration vmProperties = getVMProperties();

        final OperatingSystem os = OperatingSystem.instance();
        final ProcessManager pm = os.processManagerInstance();
        final Process process = pm.createProcess();
        final List<String> args = new ArrayList<>();
        args.add(getJavaCmd());
        getJavaOpts(args, home, vmProperties);

        if (Boolean.parseBoolean(debugLauncher)) {
            args.add("-Xdebug");
            args.add("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=4000");
        }
        args.add("-jar");
        args.add("start.jar");
        args.add(command);

        process.setWorkingDir(home);
        process.setVisible(false);
        process.setPipeStreams(false, false);
        System.out.println(String.join(" ", args));
        process.setCommand(args.toArray(new String[args.size()]));

        if (process instanceof WindowsXPProcess) {
            ((WindowsXPProcess) process).startElevated();
        } else {
            process.start();
        }
    }

    protected String getJavaCmd() {
        final File javaHome = SystemUtils.getJavaHome();
        if (SystemUtils.IS_OS_WINDOWS) {
            Path javaBin = Paths.get(javaHome.getAbsolutePath(), "bin", "javaw.exe");
            if (Files.isExecutable(javaBin)) {
                return '"' + javaBin.toString() + '"';
            }
            javaBin = Paths.get(javaHome.getAbsolutePath(), "bin", "java.exe");
            if (Files.isExecutable(javaBin)) {
                return '"' + javaBin.toString() + '"';
            }
        } else {
            Path javaBin = Paths.get(javaHome.getAbsolutePath(), "bin", "java");
            if (Files.isExecutable(javaBin)) {
                return javaBin.toString();
            }
        }
        return "java";
    }

    protected void getJavaOpts(List<String> args, String home, PropertiesConfiguration vmProperties) {
        getVMOpts(args, vmProperties);

        if (command.equals(LAUNCHER) && "mac os x".equals(OS)) {
            args.add("-Dapple.awt.UIElement=true");
        }
        args.add("-Dexist.home=\"" + home + '"');

        args.add("-Djava.endorsed.dirs=\"" + home + "/lib/endorsed\"");
    }

    protected void getVMOpts(List<String> args, PropertiesConfiguration vmProperties) {
        for (final Iterator<String> i = vmProperties.getKeys(); i.hasNext();) {
            final String key = i.next();
            if (key.startsWith("memory.")) {
                if ("memory.max".equals(key)) {
                    args.add("-Xmx" + vmProperties.getString(key) + 'm');
                } else if ("memory.min".equals(key)) {
                    args.add("-Xms" + vmProperties.getString(key) + 'm');
                }
            } else if ("vmoptions".equals(key)) {
                args.add(vmProperties.getString(key));
            } else if (key.startsWith("vmoptions.")) {
                final String os = key.substring("vmoptions.".length()).toLowerCase();
                if (OS.contains(os)) {
                    final String value = vmProperties.getString(key);
                    Arrays.stream(value.split("\\s+")).forEach(args::add);
                }
            }
        }
    }

    public static PropertiesConfiguration getVMProperties() {
        final PropertiesConfiguration vmProperties = new PropertiesConfiguration();
        final java.nio.file.Path propFile = ConfigurationHelper.lookup("vm.properties");
        InputStream is = null;
        try {
            if (Files.isReadable(propFile)) {
                is = Files.newInputStream(propFile);
            }
            if (is == null) {
                is = LauncherWrapper.class.getResourceAsStream("vm.properties");
            }
            if (is != null) {
                vmProperties.read(new InputStreamReader(is, "UTF-8"));
            }
        } catch (final IOException e) {
            System.err.println("vm.properties not found");
        } catch (ConfigurationException e) {
            System.err.println("exception reading vm.properties: " + e.getMessage());
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (final IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }
        return vmProperties;
    }
}