title: JNLP syntax for a local executable JAR in the same location
body: <p>I've seen similar questions asked on SO before, but all of them have <code>codebase/href</code> values pointing to things like <code>http://localhost:8000/test</code> and <code>file://D:/MyProject/Foo.jnlp</code> instead of supporting a completely arbitrary "run out of the same local directory" behavior.  People have mentioned that some combination of empty and/or missing attributes are supposed to work in recent JREs, but I can't find any combination of syntax that will work.  (Normally I'd just go look through the launcher source, but can't for javaws.)</p>
  
  <p>Collectively, we have a lot of experience with the Java language, but we haven't needed to use javaws before, and Oracle's documentation is... frustrating.  What we've come up with, anonymized to protect the innocent:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;jnlp spec="9+" version="x.y.z" codebase="???" href="test.jnlp"&gt;
    &lt;information&gt;
      &lt;title&gt;Our Stuff Name&lt;/title&gt;
      &lt;offline-allowed/&gt;
    &lt;/information&gt;
  
    &lt;resources&gt;
      &lt;java version="9+" java-vm-args="-X:foo"/&gt;
      &lt;java version="1.8*" java-vm-args="-X:bar"/&gt;
      &lt;jar href="OurStuff.jar" main="true"/&gt;
    &lt;/resources&gt;
  
    &lt;!-- this is apparently required for local operation even if
         the JAR has a manifest with the same main() class  --&gt;
    &lt;application-desc main-class="com.example.OurStuff"/&gt;
  
    &lt;security&gt;
      &lt;all-permissions/&gt;
    &lt;/security&gt;
  &lt;/jnlp&gt;
  </code></pre>
  
  <p>The JNLP file is included as <code>JNLP-INF/APPLICATION.JNLP</code> before signing the JAR file.  (The signing and verifying go okay, and running the signed JAR by hand using a <code>java .... -jar OurStuff.jar</code> command line works, but of course isn't available to Windows users.)</p>
  
  <p>But we don't have enough experience among us to get the codebase/href attributes right.  What we've tried:</p>
  
  <ul>
  <li><p>Any <code>codebase</code> attribute trying to refer to the current working directory, like "file://." and similar hacks, all fail with parse errors.  This makes total sense.  We tried that only out of desperation.</p></li>
  <li><p>No <code>codebase</code>, no <code>href</code> in the <code>&lt;jnlp&gt;</code> element at all:  <em>"The field href has an invalid value in the signed launch file: OurStuff.jar"</em></p></li>
  <li><p>No <code>codebase</code>, <code>&lt;jnlp href="test.jnlp"&gt;</code>:  <em>"The field href has an invalid value in the signed launch file: test.jnlp"</em></p></li>
  </ul>
  
  <p>It apparently is supposed to be able to handle only having a location URL in one place, but can't handle not having any.  Grrrr.</p>
  
  <p>We tried turning on tracing and cranked the trace level to high.  Then it gets frustrating, because at the top of the trace file, javaws had this to say:</p>
  
  <pre><code>basic: Running JVMParams: [JVMParameters: isSecure: true, args:]
      -&gt; [JVMParameters: isSecure: true, args:]
  basic: XMLParser with _source:
  &lt;?xml version="1.0" encoding="utf-8"?&gt;
  ..... our entire JNLP file verbatim including comments ......
  basic: Error parsing test.jnlp. Try to parse again with codebase from LAP
  java.net.MalformedURLException: no protocol:
      at java.base/java.net.URL.&lt;init&gt;(URL.java:627)
      .... internals stack trace .....
  </code></pre>
  
  <p>Okay, fine, it needs a well-formed URL in an href.  But later <strong>in the same trace</strong>, we see this:</p>
  
  <pre><code>temp: returning LaunchDesc from XMLFormat.parse():
  &lt;jnlp spec="9+" codebase="file:/C:/building/OurStuff/branchname/" version="x.y.x" href="file:/C:/building/OurStuff/branchname/test.jnlp"&gt;
    &lt;information&gt;
      &lt;title&gt;Our Stuff Name&lt;/title&gt;
      &lt;vendor&gt;&lt;/vendor&gt;
      &lt;offline-allowed/&gt;
    &lt;/information&gt;
    &lt;security&gt;
      &lt;all-permissions/&gt;
    &lt;/security&gt;
    &lt;update check="timeout" policy="always"/&gt;
    &lt;resources&gt;
      &lt;java version="9+"/&gt;
      &lt;java version="1.8*"/&gt;
      &lt;jar href="file:/C:/building/OurStuff/branchname/OurStuff.jar" download="eager" main="true"/&gt;
    &lt;/resources&gt;
    &lt;application-desc type="Java" main-class="com.example.OurStuff"/&gt;
  &lt;/jnlp&gt;
  </code></pre>
  
  <p>The codebase attribute, both of the href attributes, all of the missing/optional attributes, have all been worked out correctly!  Even entire elements we left out in order to get default behavior!  We were in the <code>C:\building\OurStuff\branchname</code> directory at the time!  Yay!  We thought!  Except no!  After a couple hundred more lines of <em>correctly</em> testing the signed jar's modification time, copying pieces around in its cache behind the scenes, and matching up the <code>&lt;java/&gt;</code> elements with the locally-installed JREs, it decided to ignore everything it had discovered, but instead printed out the original error and exited.</p>
  
  <p>What do we need to put in the JNLP file to tell javaws "go ahead and use the results from 'codebase from LAP'", whatever LAP means?  Or is there some other combination of codebase and href attributes that it will simply look in the same directory as the JNLP file, wherever that happens to be?</p>