JDK-8055464 : Add a URL scheme handler to reliably launch .jnlp files - java part
  • Type: Enhancement
  • Component: deploy
  • Sub-Component: webstart
  • Affected Version: 6u31
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: x86
  • Submitted: 2012-07-13
  • Updated: 2016-05-23
  • Resolved: 2015-10-14
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u72 b03Fixed 9Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
A DESCRIPTION OF THE REQUEST :
Launching Java Web Start applications from a web page is too unreliable. The current state-of-the-art method seems to be to serve a file with ".jnlp" suffix and MIME-type "application/x-java-jnlp-file". This does not work reliably. See http://crbug.com/10877 for example about the problems with Google Chrome.

  To fix the issue, Java Web Start installer should register an URL Scheme handler to reliably launch Java Web Start applications from web pages. I'd suggest scheme "javaws".

The only stuff required to start a Java Web Start application from a web page should be

    <a href="javaws://example.com/path/to/awesomeapp.jnlp">Launch the AwesomeApp</a>

Note that the URL should not require the ".jnlp" suffix. Any URL should be okay. The "javaws" scheme handler should then pass the URL to javaws or javaws.exe binary depending on the OS which should proceed to load the .jnlp file by itself. It should replace the "javaws:" prefix with "https:" to locate the actual resource. Optionally, a fallback to non-SSL connection might be allowed.

Another cool scheme name instead of "javaws" would be just "java". The scheme URL does not need to promote that this is "javaws" technology but instead it should promote "java" technology.

JUSTIFICATION :
Java Web Start is the right way to start bigger Java applications because it allows for easy updating and installing/downloading the application and allows for better UI/UX than Java applets.

However, there are some roadblocks for launching Java Web Start applications from a web page using common browsers with default settings:

1. Sun/Oracle failed to create a working browser intergration. See http://crbug.com/10877 for example about Google Chrome / Chromium. Basically the Java plugin fails to implement the required NPAPI stuff to get Firefox and Chrome to reliably forward the MIME-type application/x-java-jnlp-file to javaws / javaws.exe binary.

2. Sun/Oracle failed to get a real registered MIME-type for Java Web Start .jnlp files. The application/x- prefix technically means draft or private.

3. Sun/Oracle failed to use URL scheme instead of MIME-type when the intent is that Java Web Start handles the application downloading and launching. For example, if instead of using URL such as https://example.com/app/launch.jnlp Java Web Start were launched as javaws://example.com/app/launch.jnlp things would work much smoother. This is because in this case, the web browser does not need to even load the .jnlp file, it just passes the full URL to the scheme handler (which would be the javaws binary).

If an URL Scheme handler were used, Java Web Start applications could be *reliably* lanched also from e.g. email messages and instant message chat. Of course, allowing this makes even greater need for correctly sandboxing the application within the JVM.

Discussion: http://stackoverflow.com/questions/126260/objections-against-java-webstart

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
When I click "Launch the AwesomeApp" link on a web page the Java Web Start application "AwesomeApp" should reliably start regardless of the web browser I'm using (assuming that I've previously installed Java JRE).

If I haven't installed Java JRE, the behavior is browsers dependant but hopefully I would get error message along the lines "AwesomeBrowser cannot handle the URL Scheme 'javaws' or "Select URL Scheme handler for 'javaws://example.com/path/to/AwesomeApp.jnlp'".
ACTUAL -
Depends on browser. Currently if I try to use Java Web Start, I'm usually greeted with a "Save as..." dialog once I click a link on a web page (e.g. Google Chrome). After that I must navigate to downloaded file and e.g. double click it to launch the application. In base case, if I'm running suitable browser and I have configured it suitably, the AwesomeApp is launched once I click the link. However, that rarely works out-of-box -- the browser must be configured by hand.

---------- BEGIN SOURCE ----------
<a href="javaws://example.com/path/to/awesomeapp.jnlp">Launch the AwesomeApp</a>

or simply an URL within an email message:

javaws://example.com/path/to/awesomeapp.jnlp
or
java://example.com/path/to/awesomeapp.jnlp

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Workaround depends on a browser. For example, Google Chrome running on Ubuntu Linux requires following workaround:

1. Click a link to a .jnlp file
2. A "Save as..." dialog opens
3. Save file to somewhere
4. Notice that there's a new toolbar at the bottom of the browser window saying that the file has been successfully saved.
5. Notice that there's a tiny down arrow next to the filename.
6. Click the tiny down arrow
7. Select "Always open files of this type"
8. Click the original link again. It now works and will work the next time you try to launch the Web Start Application.

Exception:

After the app has been launched 100 times, the automatic launching will fail in Google Chrome and the Save as dialog is raised again (See the chrome bug referenced above).

Comments
OK, so the protocol does not need to match the extension. I thought there may be a reason that they would need to match but wanted to verify.
24-07-2015

no - file extension is irrelevant to deployment code, any url can return a jnlp file (web server could have servlet that generates a jnlp file ) normally jnlp mime type is only associated with files ending in ".jnlp", but server could associate it with any other extension, or servlet or server side scripting could associate it with any collection of files. javaws will normally be invoked as a helper app (file download to tmp file and passed to javaws) for any file with the mime type "application/x-java-jnlp-file" with this change, javaws will be invoked as a URL scheme handler (invoked with the URL) for any URL with the given protocol(s) - extension and mime type don't matter)
24-07-2015

Good point Chris. Andy, I assume Chris is referring to the file extension and not the protocol. Hopefully this was just a typo on your part.
24-07-2015

Andy, does jnlp and jnlps need to match: jnlp://example.com/app/launch.jnlp jnlps://example.com/app/launch.jnlps private static String filterUrlFile(String s) { // replace javaws main arg starting with "jnlp://" or "jnlps:" // with the corrisponding real protocols "http" and "https" if (s.startsWith("jnlps://")) { return s.replaceFirst("jnlps", "https"); } else if (s.startsWith("jnlp://")) { return s.replaceFirst("jnlp", "http"); } else { return s; } } because this is currently valid and I'm not sure it should be: jnlp://example.com/app/launch.jnlps or jnlps://example.com/app/launch.jnlp
24-07-2015

simple test case at http://oklahoma.us.oracle.com/www/tests/jnlp/test.html
03-06-2015

Turns out this is simple to implement and extremely powerful. I just used regedit to add a few registry keys : HKCR \ jnlp \ (Default) = "URL:jnlp Protocol" HKCR \ jnlp \ URL Protocol = "" HKCR \ jnlp \ shell \ open \ command \ (default) = "C:\Program Files (x86)\Java\jre1.8.0_60\bin\javaws.exe" "%1" and made a small change to LaunchDescFactory.buildDescriptor(String urlFile) to replace any string starting with "jnlp://" with "http://" and I can launch simple jnlp file with only: <jnlp> <resources> <jar href="hello.jar"/> </resources> <application-desc main-class="hello"/> </jnlp> simply by putting link to it with jnlp protocol instead of http protocol. I can also do the same thing registering "jnlps" protocol with : HKCR \ jnlps \ (Default) = "URL:jnlps Protocol" HKCR \ jnlps \ URL Protocol = "" HKCR \ jnlps \ shell \ open \ command \ (default) = "C:\Program Files (x86)\Java\jre1.8.0_60\bin\javaws.exe" "%1" HKCR \ jnlps \ shell \ open \ command= "C:\Program Files (x86)\Java\jre1.8.0_60\bin\javaws.exe" "%1" and replacing string starting with "jnlps://" with "https"//" in LaunchDescFactory to launch from https. There are many advantages to this. jnlp file does not need to contain codebase (much less href) because it is the same as launching from command line with fill url to the jnlp file. The codebase and href can be inferred. The browser does not have to download the jnlp file. The native code does nothing. negative side effect to this launching method is greater chance of relaunch I will use this RFE to implement the simple java side of the change, and open separate RFE for windows registration and MAC/linux registration.
03-06-2015