DankMemes
DankMemes

Reputation: 2137

Launch webstart without downloading...?

I have made a Java webstart application, and created an HTML page with the link to launch it. The problem is, in Google Chrome, there is no option to just 'Open' a file without saving it. I want to make an HTML page that can automatically launch a JNLP file without having to save it. Or rather, without the user having to open their file explorer to launch it) Is this possible?

Upvotes: 5

Views: 14546

Answers (5)

Lukas
Lukas

Reputation: 2312

For testing or webscraping (when you cannot change or control jnlp handling) I found a workaround via Selenium + Python (but similar thing should be feasible in Java or other language too). In Python I just click programmatically on the notification in Chrome to allow downloading and installation of the jnlp file (with help of win32api and win32con, but similar approach could work also on Linux or Mac, after code rework). You can see details here

Upvotes: 0

Serak Shiferaw
Serak Shiferaw

Reputation: 1021

This sample(Embedding JavaFX 2 in Swing) and articles are a great sample and they also work with modern browsers

sample http://www.oracle.com/technetwork/java/javase/overview/javafx-samples-2158687.html

documentation : https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/deployment_toolkit.html#BABIJEHC

Upvotes: 1

Chris Holt
Chris Holt

Reputation: 655

After getting fed up this problem, I wrote my own work around extension.

It's written under ubuntu, but should be portable (even to win32 with some work/reading).

Single click launches a jnlp file without prompting, or downloading. it just passes the url for the jnlp file to javaws directly. no cluttered Downloads folder, no extra clicks.

It's simple, crude and effective. I filtered the URL so it would only apply to my own internal server so I don't accidentally launch some random jnlp file. Lots more could be done to improve it, I'm sure. Use AS-IS, no warranty, etc, etc.

The files:

/usr/local/bin/jnlp-launcher

#!/usr/bin/env python

import struct
import sys
import threading
import Queue
import json
import os


# On Windows, the default I/O mode is O_TEXT. Set this to O_BINARY
# to avoid unwanted modifications of the input/output streams.
if sys.platform == "win32":
  import os, msvcrt
  msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
  msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)

# Helper function that sends a message to the webapp.
def send_message(message):
   # Write message size.
  sys.stdout.write(struct.pack('I', len(message)))
  # Write the message itself.
  sys.stdout.write(message)
  sys.stdout.flush()

# Thread that reads messages from the webapp.
def read_thread_func(queue):
  message_number = 0
  while 1:
    # Read the message length (first 4 bytes).
    text_length_bytes = sys.stdin.read(4)

    if len(text_length_bytes) == 0:
      if queue:
        queue.put(None)
      sys.exit(0)

    # Unpack message length as 4 byte integer.
    text_length = struct.unpack('i', text_length_bytes)[0]

    # Read the text (JSON object) of the message.
    text = sys.stdin.read(text_length).decode('utf-8')

    decoded = json.loads(text);
    os.system("javaws " + decoded['url']);


def Main():
  read_thread_func(None)
  send_message('"complete"')
  sys.exit(0)

if __name__ == '__main__':
  Main()

The chrome extension is 2 files placed in a local directory:

manifest.json

{
  "manifest_version": 2,

   "background": {
      "persistent": false,
      "scripts": [ "bg.js" ]
   },

  "name": "JNLP Fixer",
  "description": "Handle JNLPs",
  "version": "1.0",

  "permissions": [
    "downloads", "nativeMessaging"
  ]
}

And bg.js (edit as needed for host filters)

chrome.downloads.onCreated.addListener(function(downloadId) {
    var expr = /\.jnlp$/;
    //this is to limit where we apply the auto-launch.
    //for our use, i only wanted it for internal jnlps.
    var hostExpr = /(http|https):\/\/internal.company.com\//;
    if (hostExpr.test(downloadId.url)) {
        if (downloadId.state == "in_progress") {
            console.log(downloadId.url);
            chrome.downloads.cancel(downloadId.id,function() {
                console.log("cancelled");
            });
            chrome.runtime.sendNativeMessage("com.hcs.jnlplauncher", 
                                             {url:downloadId.url}, 
                                             function(response) 
                                             {
                    console.log(chrome.runtime.lastError);
                    console.log(response);
                    }
                );
        }
    }

})

Put manifest.json and bg.js in a folder and load it as an Unpacked extension in chrome in developer mode under chrome://extensions

Get the ID for the extension from the chrome://extensions pages.

Next is the bridge between the extension and the shell script.

File: com.hcs.jnlplauncher.json

{
  "name": "com.hcs.jnlplauncher",
  "description": "JNLP Launcher",
  "path": "/usr/local/bin/jnlp-launcher",
  "type": "stdio",
  "allowed_origins": [
    "chrome-extension://iacomlhfiphkdfjjjmlgckdkhmkhkibe/"
  ]
}

Place this under "~/.config/google-chrome/NativeMessagingHosts" (for linux). see google for windows locations.

Put your extension ID from the previous step into that file.

Make sure javaws is in the path. (that chrome runs with). link to /usr/bin is easiest way to be sure.

Click on a jnlp file and enjoy!!! No prompt, no ClickToOpen, and no file saved in the Downloads directory.!

If someone would like to bundle this all together into a nice packaged installer and/or chrome extension feel free. Please credit me (Chris Holt -- [email protected]) and let me know. At first glance, I couldn't see how to bundle the NativeMessagingHosts piece into the extension. Perhaps it has to be 2 pieces? This is my first adventure in Chrome Extensions and NativeMessaging. Most of the code comes from the API docs and examples, and there are probably a few bugs.

Upvotes: 4

Henno Vermeulen
Henno Vermeulen

Reputation: 1535

Unfortunately this is a bug(/feature?) in Google Chrome which still exists, however it is partly fixed: you can now automatically open jnlp files, but it they are still saved to the downloads folder

  • download the jnlp
  • right click in the download bar and select to always open files of this type
  • clicking the jnlp now directly launches it

Upvotes: 2

Andrew Thompson
Andrew Thompson

Reputation: 168825

Launch the JNLP using an embedded applet deployed using web start.

  1. Start with a Swing based JApplet that accepts an image path (icon) and a string for the button. Deploy the applet (embedded in the web page, where the link would be) using JWS.
  2. When the user clicks the button, use the BasicService.showDocument(URL) method to launch the JWS (frame based) app. As I note in the demo. of the BasicService..

    ..In Java 6+, a call to show another web start launch file (e.g. BasiceService.showDocument(another.jnlp)) will be handed directly to JavaWS, with no browser window appearing.

Upvotes: 2

Related Questions