package jalview.bin; import java.io.File; import java.io.IOException; import java.lang.management.ManagementFactory; import java.util.ArrayList; public class Launcher { private final static String startClass = "jalview.bin.Jalview"; private final static int maxHeapSizePerCent = 90; private final static String maxHeapSizePerCentProperty = "jvmmempc"; private final static String dockIconPath = "JalviewLogo_Huge.png"; public static void main(String[] args) { final String javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"; ArrayList command = new ArrayList<>(); command.add(javaBin); String memSetting = null; boolean isAMac = System.getProperty("os.name").indexOf("Mac") > -1; for (String jvmArg : ManagementFactory.getRuntimeMXBean() .getInputArguments()) { command.add(jvmArg); } command.add("-cp"); command.add(ManagementFactory.getRuntimeMXBean().getClassPath()); ArrayList arguments = new ArrayList<>(); for (String arg : args) { arguments.add(arg); } // add memory setting if not specified boolean memSet = false; boolean dockIcon = false; boolean dockName = false; ARG: for (int i = 0; i < command.size(); i++) { String arg = command.get(i); if (arg.startsWith("-Xmx")) { memSetting = arg; memSet = true; } else if (arg.startsWith("-Xdock:icon")) { dockIcon = true; } else if (arg.startsWith("-Xdock:name")) { dockName = true; } } if (!memSet) { long maxMemLong = -1; int percent = maxHeapSizePerCent; String jvmmempc = System.getProperty(maxHeapSizePerCentProperty); try { if (jvmmempc != null) { int trypercent = Integer.parseInt(jvmmempc); if (0 < trypercent && trypercent <= 100) { percent = trypercent; } else { System.out.println("Property '" + maxHeapSizePerCentProperty + "' should be in range 1..100"); } } } catch (Exception e) { System.out.println("Error parsing " + maxHeapSizePerCentProperty + " '" + jvmmempc + "'"); } try { maxMemLong = MemorySetting.memPercent(percent); } catch (Exception e) { e.printStackTrace(); } catch (Throwable t) { t.printStackTrace(); } if (maxMemLong > 0) { memSetting = "-Xmx" + Long.toString(maxMemLong); command.add(memSetting); } } if (isAMac) { if (!dockIcon) { command.add("-Xdock:icon=" + dockIconPath); } if (!dockName) { // -Xdock:name=... doesn't actually work :( // Leaving it in in case it gets fixed command.add("-Xdock:name=" + "Jalview"); } } command.add(startClass); command.addAll(arguments); final ProcessBuilder builder = new ProcessBuilder(command); // System.out.println("COMMAND: " + String.join(" ", builder.command())); System.out.println("Running " + startClass + " with " + (memSetting == null ? "no memSetting" : memSetting)); try { builder.inheritIO(); Process process = builder.start(); process.waitFor(); } catch (IOException e) { if (e.getMessage().toLowerCase().contains("memory")) { System.out.println("Caught a memory exception: " + e.getMessage()); // Probably the "Cannot allocate memory" error, try without the memory setting ArrayList commandNoMem = new ArrayList<>(); for (int i = 0; i < command.size(); i++) { if (!command.get(i).startsWith("-Xmx")) { commandNoMem.add(command.get(i)); } } final ProcessBuilder builderNoMem = new ProcessBuilder( commandNoMem); System.out.println("NO MEM COMMAND: " + String.join(" ", builderNoMem.command())); try { builderNoMem.inheritIO(); Process processNoMem = builderNoMem.start(); processNoMem.waitFor(); } catch (Exception ex) { ex.printStackTrace(); } } else { e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } // System.exit(0); } }