diff --git a/src/main/java/com/threerings/getdown/data/Application.java b/src/main/java/com/threerings/getdown/data/Application.java
index 415537b..f883d05 100644
--- a/src/main/java/com/threerings/getdown/data/Application.java
+++ b/src/main/java/com/threerings/getdown/data/Application.java
@@ -545,6 +545,7 @@ public class Application
_auxrsrcs.clear();
_jvmargs.clear();
_appargs.clear();
+ _txtJvmArgs.clear();
// parse our code resources
if (ConfigUtil.getMultiValue(cdata, "code") == null) {
@@ -578,6 +579,9 @@ public class Application
_jvmargs.add(arg);
}
+ // get the set of optimum JVM arguments
+ _optimumJvmArgs = ConfigUtil.getMultiValue(cdata, "optimum_jvmarg");
+
// transfer our application arguments
String[] appargs = ConfigUtil.getMultiValue(cdata, prefix + "apparg");
if (appargs != null) {
@@ -592,7 +596,7 @@ public class Application
}
// look for custom arguments
- fillAssignmentListFromPairs("extra.txt", _jvmargs);
+ fillAssignmentListFromPairs("extra.txt", _txtJvmArgs);
// determine whether we want to allow offline operation (defaults to false)
_allowOffline = Boolean.parseBoolean((String)cdata.get("allow_offline"));
@@ -712,6 +716,16 @@ public class Application
return version >= _javaVersion;
}
+ /**
+ * Checks whether the app has a set of "optimum" JVM args that we wish to try first, detecting
+ * whether the launch is successful and, if necessary, trying again without the optimum
+ * arguments.
+ */
+ public boolean hasOptimumJvmArgs ()
+ {
+ return _optimumJvmArgs != null;
+ }
+
/**
* Attempts to redownload the getdown.txt file based on information parsed from a
* previous call to {@link #init}.
@@ -764,8 +778,11 @@ public class Application
/**
* Invokes the process associated with this application definition.
+ *
+ * @param optimum whether or not to include the set of optimum arguments (as opposed to falling
+ * back).
*/
- public Process createProcess ()
+ public Process createProcess (boolean optimum)
throws IOException
{
// create our classpath
@@ -816,6 +833,18 @@ public class Application
args.add(processArg(string));
}
+ // add the optimum arguments if requested and available
+ if (optimum && _optimumJvmArgs != null) {
+ for (String string : _optimumJvmArgs) {
+ args.add(processArg(string));
+ }
+ }
+
+ // add the arguments from extra.txt (after the optimum ones, in case they override them)
+ for (String string : _txtJvmArgs) {
+ args.add(processArg(string));
+ }
+
// add the application class name
args.add(_class);
@@ -1548,6 +1577,10 @@ public class Application
protected String[] _extraJvmArgs;
protected String[] _extraAppArgs;
+ protected String[] _optimumJvmArgs;
+
+ protected List _txtJvmArgs = new ArrayList();
+
protected List _signers;
/** If a warning has been issued about not being able to set modtimes. */
diff --git a/src/main/java/com/threerings/getdown/launcher/Getdown.java b/src/main/java/com/threerings/getdown/launcher/Getdown.java
index f54a505..e099127 100644
--- a/src/main/java/com/threerings/getdown/launcher/Getdown.java
+++ b/src/main/java/com/threerings/getdown/launcher/Getdown.java
@@ -63,6 +63,8 @@ import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
import ca.beq.util.win32.registry.RegistryKey;
import ca.beq.util.win32.registry.RegistryValue;
@@ -748,7 +750,33 @@ public abstract class Getdown extends Thread
_app.invokeDirect(getApplet());
} else {
- Process proc = _app.createProcess();
+ Process proc;
+ if (_app.hasOptimumJvmArgs()) {
+ // if we have "optimum" arguments, we want to try launching with them first
+ proc = _app.createProcess(true);
+
+ // wait a short amount of time for the process to exit; if it doesn't (or it
+ // exits with a success code), assume everything's good
+ Timer timer = new Timer("fallbackCheck", true);
+ timer.schedule(new TimerTask() {
+ @Override public void run () {
+ Getdown.this.interrupt();
+ }
+ }, FALLBACK_CHECK_TIME);
+ boolean error;
+ try {
+ error = (proc.waitFor() != 0);
+ } catch (InterruptedException e) {
+ error = false;
+ }
+ timer.cancel();
+ if (error) {
+ log.info("Failed to launch with optimum arguments; falling back.");
+ proc = _app.createProcess(false);
+ }
+ } else {
+ proc = _app.createProcess(false);
+ }
// close standard in to avoid choking standard out of the launched process
proc.getInputStream().close();
@@ -1081,6 +1109,7 @@ public abstract class Getdown extends Thread
protected static final int MAX_LOOPS = 5;
protected static final long MIN_EXIST_TIME = 5000L;
+ protected static final long FALLBACK_CHECK_TIME = 1000L;
protected static final String PROXY_REGISTRY =
"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
}