title: How can dynamic JVM command line flags be passed to a self-contained JavaFX application?
body: <p><em>EDIT: Oracle accept my bug report requesting an enhancement as <a href="https://bugs.openjdk.java.net/browse/JDK-8138944" rel="nofollow noreferrer">JDK-8138944 : Support command line arguments to the JVM passed to self-contained app launchers</a>.</em></p>
  
  <h2>The problem</h2>
  
  <p>My team is working on an open source Java SE project, <a href="https://github.com/imagej/imagej" rel="nofollow noreferrer">ImageJ</a>, that currently has a <a href="https://github.com/imagej/imagej-launcher" rel="nofollow noreferrer">custom native launcher</a> written in cross-platform C. We would like to move away from this launcher, switching to a more modern, industry standard and maintainable deployment mechanism. <a href="http://docs.oracle.com/javase/8/docs/technotes/guides/deploy/self-contained-packaging.html" rel="nofollow noreferrer">JavaFX self-contained applications</a> are the most promising solution we have found so far.</p>
  
  <p>One great feature of ImageJ's current native launcher is its ability to customize how the JVM is launched. For example, you can write:</p>
  
  <pre><code>ImageJ --debugger=8000 myFile.png
  </code></pre>
  
  <p>And the launcher will invoke the JVM with flag:</p>
  
  <pre><code>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=localhost:8000
  </code></pre>
  
  <p>while keeping the <code>myFile.png</code> as an argument to the Java main class.</p>
  
  <p>But from the docs, we cannot see a way to accomplish something similar with the JavaFX packaging tool.</p>
  
  <h2>Considerations</h2>
  
  <p>I know that the <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/jvm_options_api.html" rel="nofollow noreferrer">UserJvmOptionsService</a> provides a means to configure how the JVM is started (via Java Preferences API internally, which the JavaFX launcher reads before JVM startup). This is nice for providing the user with a friendly dialog box where they can tweak maximum heap size and other common parameters. Certainly we could add a remote debugging toggle and port settings to such a dialog box, and/or support JVM configuration via the CLI—but it would then require a restart of the application.</p>
  
  <p>Ideally we would not need to support this scenario at all, and instead would handle <em>all</em> command line arguments after the JVM starts up, in Java. For example, in most cases, system properties of the form <code>-Dfoo=bar</code> can be supported by simply parsing the arg and setting the system property at runtime, as long as it is done early enough in the application's startup cycle. But there are clearly many cases where doing it after JVM startup is too late:</p>
  
  <ul>
  <li>The debugging example above (you <a href="https://stackoverflow.com/q/376201/1207769">can't enable remote debugging after startup</a>).</li>
  <li>Heap size tuning</li>
  <li>Garbage collection tuning</li>
  <li>Verbose class loading (<code>-verbose</code>)</li>
  <li>Interpreted mode (<code>-Xint</code>)</li>
  <li><a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html#CBBIJCHG" rel="nofollow noreferrer">Lots of other examples</a></li>
  </ul>
  
  <p>Our users expect to be able to pass these settings on the CLI, and have the Java runtime operate accordingly—and in the case of ImageJ, it is particularly important for backward compatibility.</p>
  
  <h2>Possible solutions</h2>
  
  <ul>
  <li><p>We could retain the native C launcher, replacing the native executable that the Java packaging tool installs. But this strikes me as highly fragile, and largely defeats the purpose of switching to JavaFX deployment, since we would still need to maintain, build and test the custom native launcher across several different platforms.</p></li>
  <li><p>Alternately, we could have the application main class be a very thin CLI option parser, which then spawns a second instance of the JVM. This would keep the bootstrapping logic in pure Java, which would be far more maintainable than the current native C code, while fully leveraging the JavaFX deployment scheme's cross-platform bundling capabilities. But that seems like a big hack with potentially challenging side effects.</p></li>
  </ul>
  
  <h2>Finally, the question</h2>
  
  <p><strong>Has anyone achieved support for JVM CLI arguments with JavaFX self-contained application deployment?</strong> If so, how did you accomplish it? If not, any alternative suggestions?</p>