Merge branch 'develop' into releases/Release_2_11_Branch
[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 maxHeapSizePerCentProperty = "jvmmempc";
16
17   private final static String dockIconPath = "JalviewLogo_Huge.png";
18
19   public static void main(String[] args)
20   {
21     final String javaBin = System.getProperty("java.home") + File.separator
22             + "bin" + File.separator + "java";
23
24     ArrayList<String> command = new ArrayList<>();
25     command.add(javaBin);
26
27     String memSetting = null;
28
29     boolean isAMac = System.getProperty("os.name").indexOf("Mac") > -1;
30
31     for (String jvmArg : ManagementFactory.getRuntimeMXBean()
32             .getInputArguments())
33     {
34       command.add(jvmArg);
35     }
36     command.add("-cp");
37     command.add(ManagementFactory.getRuntimeMXBean().getClassPath());
38     ArrayList<String> arguments = new ArrayList<>();
39     for (String arg : args)
40     {
41       arguments.add(arg);
42     }
43
44     // add memory setting if not specified
45     boolean memSet = false;
46     boolean dockIcon = false;
47     boolean dockName = false;
48     ARG: for (int i = 0; i < command.size(); i++)
49     {
50       String arg = command.get(i);
51       if (arg.startsWith("-Xmx"))
52       {
53         memSetting = arg;
54         memSet = true;
55       }
56       else if (arg.startsWith("-Xdock:icon"))
57       {
58         dockIcon = true;
59       }
60       else if (arg.startsWith("-Xdock:name"))
61       {
62         dockName = true;
63       }
64     }
65
66     if (!memSet)
67     {
68       long maxMemLong = -1;
69       int percent = maxHeapSizePerCent;
70       String jvmmempc = System.getProperty(maxHeapSizePerCentProperty);
71       try
72       {
73         if (jvmmempc != null)
74         {
75           int trypercent = Integer.parseInt(jvmmempc);
76           if (0 < trypercent && trypercent <= 100)
77           {
78             percent = trypercent;
79           }
80           else
81           {
82             System.out.println("Property '" + maxHeapSizePerCentProperty
83                     + "' should be in range 1..100");
84           }
85         }
86       } catch (Exception e)
87       {
88         System.out.println("Error parsing " + maxHeapSizePerCentProperty
89                 + " '" + jvmmempc + "'");
90       }
91
92       try
93       {
94         maxMemLong = MemorySetting.memPercent(percent);
95       } catch (Exception e)
96       {
97         e.printStackTrace();
98       } catch (Throwable t)
99       {
100         t.printStackTrace();
101       }
102
103       if (maxMemLong > 0)
104       {
105         memSetting = "-Xmx" + Long.toString(maxMemLong);
106         command.add(memSetting);
107       }
108     }
109
110     if (isAMac)
111     {
112       if (!dockIcon)
113       {
114         command.add("-Xdock:icon=" + dockIconPath);
115       }
116       if (!dockName)
117       {
118         // -Xdock:name=... doesn't actually work :(
119         // Leaving it in in case it gets fixed
120         command.add("-Xdock:name=" + "Jalview");
121       }
122     }
123
124     command.add(startClass);
125     command.addAll(arguments);
126
127     final ProcessBuilder builder = new ProcessBuilder(command);
128
129     // System.out.println("COMMAND: " + String.join(" ", builder.command()));
130     System.out.println("Running " + startClass + " with "
131             + (memSetting == null ? "no memSetting" : memSetting));
132
133     try
134     {
135       builder.inheritIO();
136       Process process = builder.start();
137       process.waitFor();
138     } catch (IOException e)
139     {
140       if (e.getMessage().toLowerCase().contains("memory"))
141       {
142         System.out.println("Caught a memory exception: " + e.getMessage());
143         // Probably the "Cannot allocate memory" error, try without the memory setting
144         ArrayList<String> commandNoMem = new ArrayList<>();
145         for (int i = 0; i < command.size(); i++)
146         {
147           if (!command.get(i).startsWith("-Xmx"))
148           {
149             commandNoMem.add(command.get(i));
150           }
151         }
152         final ProcessBuilder builderNoMem = new ProcessBuilder(
153                 commandNoMem);
154         System.out.println("NO MEM COMMAND: "
155                 + String.join(" ", builderNoMem.command()));
156         try
157         {
158           builderNoMem.inheritIO();
159           Process processNoMem = builderNoMem.start();
160           processNoMem.waitFor();
161         } catch (Exception ex)
162         {
163           ex.printStackTrace();
164         }
165       }
166       else
167       {
168         e.printStackTrace();
169       }
170     } catch (Exception e)
171     {
172       e.printStackTrace();
173     }
174     // System.exit(0);
175
176   }
177
178 }