How to communicate between browser and Java Web Start applet
Asked Answered
F

2

8

Current situation

We currently use an applet to perform some operations, after which it redirects the current page. In its core, you could see the applet as the following:

public class ExampleApplet extends Applet {
    @Override
    public void init() {
        Button redirect = new Button("Redirect");
        this.add(redirect);
        final String target = this.getParameter("targetPage");
        redirect.addActionListener((ActionEvent e) -> {
            try {
                getAppletContext().showDocument(new URL(target), "_parent");
            } catch (MalformedURLException ex) {}
        });
    }
}

with the applet being called in its simplest way:

<applet code="com.example.applet.ExampleApplet.class" archive="${appletUrl}" width="100" height="30">
    <param name="targetPage" value="http://localhost:8080/applet/"/>
</applet><br/><br/>

where ${appletUrl} returns the location of the applet JAR.

So the applet is nothing more than a simple button that calls getAppletContext().showDocument(new URL(target), "_parent"); to refresh the current page. This has done its job correctly for a long time. Now here's the issue.

Migration

As many may know, Chrome does not support Applets. Which was put aside for a while since IE and FireFox still supported them. At the end of 2016, they will also no longer support them. So we decided to migrate the applet using JWS and JNLP.

Migrating this simple redirect button example would give the following html snippet and JNLP file:

<a href="${jnlpUrl}">Launch JNLP</a>

${jnlpUrl} returns the location to the JNLP file which is:

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://localhost:8080/applet/assets/1.0-SNAPSHOT-DEV/app/assets/" href="jnlp/example.jnlp">
    <security>
        <all-permissions/>
    </security>
    <resources>
        <j2se version="1.5+" initial-heap-size="32m" max-heap-size="128m" />
        <property name="jnlp.versionEnabled" value="false"/>
        <jar href="applets/ExampleApplet.jar" main="true"/>
    </resources>
    <applet-desc name="code" main-class="com.example.applet.ExampleApplet.class" width="30" height="30" >
        <param name="targetPage" value="http://localhost:8080/applet/"/>
    </applet-desc>
</jnlp>

So far so good, the same applet successfuly deploys as a JWS application. Allowing it to be used from any browser since it's executed outside of it. Which also is kind of the problem.

The problem

The line getAppletContext().showDocument(new URL(target), "_parent"); still does a redirect, but it's using the default browser as stated in the migration documentation.

For AppletContext.showDocument(URL url, String target), the target argument will be ignored by Java Web Start technology.

Similar to AppletContext.showDocument, Java Web Start applications are capabile of showing an HTML page using the system's default web browser by using the BasicService.showDocument API.

So if my default browser is FireFox, but I happen to be browsing to this JWS-enabled applet in IE/Chrome, a new tab will be opened in FireFox. This is a problem, since I have information (e.g. login) stored in the original browser!

Findings

Since the application is running outside of the browser, I'm having issues to think of possibilities to communicate back to the original browser. I can't use JavaScript since it doesn't run within the browser. I can't really define a system-independent way to open a tab in the original browser. I've also thought of WebSockets since they could allow direct communication, but from what I've read it's pretty high-level and requires a server, not a simple applet.

Is there any possibility of communicating between the original browser (e.g. websockets and parameters) or passing the session from one browser to another when the applet opens a new window?

Filling answered 16/6, 2016 at 14:43 Comment(5)
I know the problem... however in your case, why do you use the applet to simply refresh the browser window? Why not use just only javascript w/o any applet? At the place where you build your jnlp, could you insert that authentication stuff somehow as another param that the applet then could append to the showDocument in the other browser?Valentinavalentine
@StefanHegny Unfortunately, the applet does a lot more than a refresh. More than what's possible with Javascript. The redirect applet is just a minimal example of the issue I'm facing. I will take a look into appending required parameters to my target URL however. A good idea to start with!Filling
Ok, could have guessed it...I have similar problems (#37316319) but I think I'm giving up... good luck to youValentinavalentine
"Chrome does not support Applets. Which was put aside for a while since IE and FireFox still supported them. At the end of 2016, they will also no longer support them. So we decided to migrate the applet using JWS and JNLP." You have this a bit mixed up. 1) Firstly, that applet launch is in no way using JWS/JNLP. 2) A JWS launched free floating applet has been possible ever since JWS was introduced, but around 1.6.0_10 they added the ability to keep a JWS launched applet embedded within the web page. 4) When Chrome removes the plug-in, neither form of embedded applet is possible. ..Whyte
.. 5) At to the free floating applet, as long as the user had the Java Plug-In installed, clicking a link to a JNLP could cause it to be passed direct to the JavaWS launcher and the plug-in would handle it from there. Now they've removed support for the plug-in (already in my Chrome) if I click a link to a JNLP it will just download it, and I'd have to double click the file in the downloads. 6) Almost forgot, only an embedded Java applet can interact JS in a web page. If an applet has been initially launched free floating, or been dragged off the web page, it will not be able to interact.Whyte
F
5

I have found out a working solution.

Since the applet loses all connection to the browser and its session, another way to provide communication is with WebSockets or Comet. In my case I used Comet with the Atmosphere framework and a Tapestry-Atmosphere implementation, since Tapestry is the view-framework I'm using.

Without going too deep into the Tapestry implementation, I have done the following:

  • Set up a Topic on the client-side browser which will listen to broadcasted messages in a typical publish/subscribe manner.
  • Provide the Topic's ID which is unique to the current browsing user into the Applet, along with a URL to send a request to. Using the Topic ID as a request parameter for the url.
  • Server-side I have the endpoint of the request which receives the Topic as a request parameter. Using this parameter, it sends a broadcast (possibly empty) to the topic.
  • The client-side Topic receives the notification and executes an event in itself. The event being to re-render specific content of the page.

Since it's using Comet (but could also use WebSockets) it happens directly in the browser. Every browser subscribed to that Topic actually, but here there's only one.

Making it in fact possible, to update the page from a simple request from the applet. The applet only had the line getAppletContext().showDocument(new URL(target), "_parent"); changed to new URL(target).openConnection().getInputStream();. With target being a URL with the included request parameter.

Filling answered 22/6, 2016 at 10:11 Comment(0)
R
2

This is an answer to an old thread. We faced a similar situation in our environment. This is how it was addressed.

Can an Applet that uses JavaScript to communicate with web server be migrated to JWS?

The solution was something similar as described by James. We maintained a hashmap of requests at server end with uid as the key. The webapplication then keeps long polling the server to check for JWS status; and JWS POSTs the status to server.

We did not use any third party components; it was simple connection to URL.

Resurgent answered 26/9, 2016 at 12:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.