JAL-3254 Improved memory setting (allows mem for OS). Moved OperatingSystemMXBean...
[jalview.git] / src / jalview / bin / Launcher.java
1 package jalview.bin;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.lang.management.ManagementFactory;
6 import java.util.ArrayList;
7
8 public class Launcher
9 {
10
11   private final static String startClass = "jalview.bin.Jalview";
12
13   private final static int maxHeapSizePerCent = 90;
14
15   private final static String dockIconPath = "JalviewLogo_Huge.png";
16
17   public static void main(String[] args)
18   {
19     final String javaBin = System.getProperty("java.home") + File.separator
20             + "bin" + File.separator + "java";
21
22     ArrayList<String> command = new ArrayList<>();
23     command.add(javaBin);
24
25     boolean isAMac = System.getProperty("os.name").indexOf("Mac") > -1;
26
27     for (String jvmArg : ManagementFactory.getRuntimeMXBean()
28             .getInputArguments())
29     {
30       command.add(jvmArg);
31     }
32     command.add("-cp");
33     command.add(ManagementFactory.getRuntimeMXBean().getClassPath());
34     ArrayList<String> arguments = new ArrayList<>();
35     for (String arg : args)
36     {
37       arguments.add(arg);
38     }
39
40     // add memory setting if not specified
41     boolean memSet = false;
42     boolean dockIcon = false;
43     boolean dockName = false;
44     ARG: for (int i = 0; i < command.size(); i++)
45     {
46       String arg = command.get(i);
47       if (arg.startsWith("-Xmx"))
48       {
49         memSet = true;
50       }
51       else if (arg.startsWith("-Xdock:icon"))
52       {
53         dockIcon = true;
54       }
55       else if (arg.startsWith("-Xdock:name"))
56       {
57         dockName = true;
58       }
59     }
60
61     if (!memSet)
62     {
63       long maxMemLong = -1;
64
65       try
66       {
67         maxMemLong = MemorySetting.memPercent(maxHeapSizePerCent);
68       } catch (Exception e)
69       {
70         e.printStackTrace();
71       } catch (Throwable t)
72       {
73         t.printStackTrace();
74       }
75
76       if (maxMemLong > 0)
77       {
78         command.add("-Xmx" + Long.toString(maxMemLong));
79       }
80     }
81
82     if (isAMac)
83     {
84       if (!dockIcon)
85       {
86         command.add("-Xdock:icon=" + dockIconPath);
87       }
88       if (!dockName)
89       {
90         // -Xdock:name=... doesn't actually work :(
91         // Leaving it in in case it gets fixed
92         command.add("-Xdock:name=" + "Jalview");
93       }
94     }
95
96     command.add(startClass);
97     command.addAll(arguments);
98
99     final ProcessBuilder builder = new ProcessBuilder(command);
100
101     System.out.println("COMMAND: " + String.join(" ", builder.command()));
102
103     try
104     {
105       builder.inheritIO();
106       Process process = builder.start();
107       process.waitFor();
108     } catch (IOException e)
109     {
110       if (e.getMessage().toLowerCase().contains("memory"))
111       {
112         System.out.println("Caught a memory exception: " + e.getMessage());
113         // Probably the "Cannot allocate memory" error, try without the memory setting
114         ArrayList<String> commandNoMem = new ArrayList<>();
115         for (int i = 0; i < command.size(); i++)
116         {
117           if (!command.get(i).startsWith("-Xmx"))
118           {
119             commandNoMem.add(command.get(i));
120           }
121         }
122         final ProcessBuilder builderNoMem = new ProcessBuilder(
123                 commandNoMem);
124         System.out.println("NO MEM COMMAND: "
125                 + String.join(" ", builderNoMem.command()));
126         try
127         {
128           builderNoMem.inheritIO();
129           Process processNoMem = builderNoMem.start();
130           processNoMem.waitFor();
131         } catch (Exception ex)
132         {
133           ex.printStackTrace();
134         }
135       }
136       else
137       {
138         e.printStackTrace();
139       }
140     } catch (Exception e)
141     {
142       e.printStackTrace();
143     }
144     // System.exit(0);
145
146   }
147
148 }