FilippSmirnov FilippSmirnov - 3 months ago 12
Java Question

Is it possible to get browsers installed using JNLP

I am using JNLP to start my.jar the example of JNLP is bellow:

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+"
codebase="https://***"
href="my.jnlp">
<information>
<title>***</title>
<offline-allowed/>
</information>
<resources>
<jar href="lib/my.jar"/>
<j2se version="1.8+"
href="http://java.sun.com/products/autodl/j2se"/>
</resources>
<security>
<all-permissions/>
</security>
<application-desc main-class="my.gui.***">
<argument>-browser.cmd=firefox</argument>
</application-desc>
</jnlp>


As you can see I set a variable browser.cmd:

<argument>-browser.cmd=firefox</argument>


It used in my.jar to open HTML content in browser specified. But unfortunately it does not work for some cases.

So I think it is possible to write function in JNLP which will return browser list installed in system these value will be used like this:

browser.cmd = returned values.

Is it possible to implement by JNLP means?

Answer

You cannot add any code to JNLP descriptor. It is pure declaration.

I'd suggest you several solutions.

If you use this to open specific browser, the best solution is to use API:

    if(Desktop.isDesktopSupported()){
        Desktop desktop = Desktop.getDesktop();
        try {
            desktop.browse(new URI(url));
        } catch (IOException | URISyntaxException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

It is considered a bad style to run specific browser as an external process for various reasons.

However as far as I understand you cannot change the application.

The second solution is the following. You can implement your own "browser discoverer." Run this discoverer using JNLP, discover the browser and then run your "real" application either via JNLP or, even better, directly from your discoverer passing the browser as a parameter.

This solution will work if you can discover the "right" browser. Such task however cannot be implemented using any cross platform way. For example on Windows you can check registry, on Linux it depends on the flavor etc.

Other, may be strange but IMHO the best solution is the following. You can use AOP to wrap Runtime.exec() method. Now pass very special, not existing parameter instead of browser, let's say "my-default-browser". You can discover this string into the aspect and call regular exec() unless the command equals to this special value. However in your special case you can invoke desktop.browse(new URI(url)); (see the beginning of my answer).

This solution probably sounds complicated but in fact it is not. You can implement 5-lines long aspect using AspectJ that does this. This solution will solve the "crime" committed by somebody that ran browser by creating new process manually and whose code you cannot change. This solution will be portable and work on any platform and will not depend on what browsers are installed on the system and whether current user can run them.