/* * 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; } }