How to use Java applets in modern browsers

Saturday, January 28. 2012

How to use Java applets in modern browsers

Finding out how to embed a Java applet in current major browsers is quite a task. Lots of pages still suggest using the <applet> tag and describe how to use the mayscript attribute to allow communication between Java and JavaScript. Other pages recommend using this mysterious mayscript attribute even in <embed> and <object> tags. I think there is a lot of voodoo out there, attributes which sound important but are not necessary at all...

So I started studying this stuff by myself. My goal was embedding a Java applet on a page which must work in Internet Explorer 7+, Google Chrome, Firefox, Opera and Safari. The applet must receive an applet parameter and must communicate with JavaScript in both directions.

The <applet> tag

First of all I searched for some official statement which confirms that the <applet> tag is deprecated. Found it in the HTML 5 spec

The applet element is a Java-specific variant of the embed element. The applet element is now obsoleted so that all extension frameworks (Java, .NET, Flash, etc) are handled in a consistent manner.

So the <applet> tag is out of the game.

The <embed> tag

I was surprised seeing the <embed> tag mentioned in the HTML 5 spec because this tag was considered deprecated by older HTML versions. So it is no longer deprecated in HTML 5 and we can use it. Nice thing about this: The <embed> tag is pretty old and even ancient Netscape browsers supported it so we have a broad range of supporting browsers here.

The <embed> tag is used like this:

<embed id="testapplet"
       type="application/x-java-applet;version=1.6"
       width="256" height="256" 
       archive="mytest.jar"
       code="my.package.MyClass"
       pluginspage="http://java.com/download/"
       myParam="My Param Value" />

The above code works in all major browsers, even in Internet Explorer. You can specify the minimum Java version your applet needs with the version argument in the mime type. But what happens when Java is not installed or the installed version is too old?

  • Firefox: Informs the user about the missing plugin by displaying a message and a link in the applet area. Clicking the link opens a dialog window and Firefox tries to locate a matching plugin. It doesn't find one (I guess this works only for Flash plugin?) but then suggests a manual install and displays a button which links to the URL which is specified by the pluginspage attribute in the <embed> tag. If you are only interested in supporting Windows then you can link directly to one of the XPI installers provided by Oracle.
  • Safari: Displays a "Missing Plugin" message in the applet area together with a link pointing to the page specified by the pluginspage attribute.
  • Opera: The same as Safari. Provides a link to the page specified by the pluginspage attribute.
  • Chrome: Ignores the pluginspage attribute but knows that we want to have Java here so it displays a message in the applet area with a hardcoded link to http://java.com/download/.
  • Internet Explorer: No message, no link. Just an icon which may want to visualize a missing plugin.

The <object> tag

If you don't care about an easy Java installation in Internet Explorer then you can stick with using the <embed> tag as described above. But if you want a more userfriendly approach then you have to use an Internet Explorer specific technique together with the above <embed> tag. It works like this:

<object id="testapplet-object" 
        classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
        width="256" height="256"
        codebase="http://java.sun.com/update/1.6.0/jinstall-6u30-windows-i586.cab#Version=1,6,0,0">
  <param name="archive" value="mytest.jar" />
  <param name="code" value="my.package.MyClass" />
  <param name="myParam" value="My Param Value" />
  <embed id="testapplet-embed"
         type="application/x-java-applet;version=1.6"
         width="256" height="256" 
         archive="mytest.jar"
         code="my.package.MyClass" 
         pluginspage="http://java.com/download/"
         myParam="My Param Value" />
  </embed>
</object>

So the <embed> element is now a child element of the <object> element and serves as a fallback. All browsers which don't know what to do with this <object> element and its classid attribute will fall back to the <embed> element. Only Internet Explorer knows what to do with this classid. The codebase attribute defines the URL from which IE can download the Java installer and it also defines the minimum version of the plugin. So when no Java is installed or the installed version is older than this specified version then IE automatically downloads the installer and starts it. It even reloads the page after the installation of Java so this solution is very user-friendly.

You can find a list of installer URLs here.

While applet parameters are specified with tag attributes for the <embed> tag you now also have to specify them with <param> tags for the <object> tag.

Calling the Java applet from JavaScript

Public methods of the Java applet can be called directly from JavaScript but the problem is getting the Java applet reference. If you only use the <embed> tag then this is pretty simple:

document.getElementById("testapplet").myMethod();

But when you are also using the <object> tag then it is a little bit more complicated. Internet Explorer must use the first element, all others must use the second. So some kind of browser detection is needed here. I recommend using Conditional Compilation to do this:

function getApplet()
{
    /*@cc_on return document.getElementById("testapplet-object") @*/
    return document.getElementById("testapplet-embed");
}

The first line is only executed by Internet Explorer so IE returns the element with the ID testapplet-object. All other browsers execute the last line which returns the element with the ID testapplet-embed.

So now you can execute a method of the Java applet like this:

getApplet().myMethod();

You can find a complete example with Java source code of a test applet here.

Posted in Java, JavaScript | Comments (9)
Ghetolay at 2012-05-28 17:22
Wonderful !!

I think you saved a life because I almost committed suicide trying to resolve that.

Sun/Oracle offer javascript file deployJava.js and dtJava.js but it's not really effective and up to date.

Thanks a lot.
lo at 2012-11-12 18:11
Hey,

It's a nice write-up, but I don't see the same result in my experimentation, as I was attempting something similar. For me, the `applet` tag was the only one working for IE7/IE8 (IE9+ is fine with `object`). But I think the reason is situational: my code wasn't pre-generated and statically loaded at the page's loading time, but being injected directly into the page at runtime.

And apparently in this case, IE7/8 refuses to trigger the applet's startup when using `object`. But when you go back to good ol' `applet` tag, it worked like a charm.

So, unfortunately, in the case of dynamic applet injection, it looks like you still need to browser sniff a bit in JS to decide whether to include object+embed or applet. Or you can use conditional comments for IE.
lo at 2012-11-12 18:13
Also, you might want to inject the `embed` tag wrapped in a `comment` tag. But be careful that some browsers won't like that.

Guess which one? IE8 of course. But once again, I think this only causes a problem when the markup is created at runtime, and it will ignore at load-time if statically loaded.
But if you build it dynamically with JS, be sure to wrap the code that appends the `embed` tag to the `comment` tag with a try/catch.
lo at 2012-11-12 18:27
Just came across a post that confirms my experimentation (I can't believe, been working on this for 2 weeks to fine-tune various details, so obviously I looked-up a lot of docs online, and it's the first I see this post):

http://windyroad.org/2006/08/14/reintroducing-javascript-and-hidden-applets-jaha/
applet at 2012-11-23 12:00
I've been using jQuery to add an applet to a page after the DOM has loaded, ie onDocumentReady(). I'm using the object tag. This works with IE 8.0.6001 and Firefox 16.0.2. Dynamically loading java applets isn't straight forward and you'll find more information on stackoverflow.
lo at 2013-01-21 15:02
Unrelated to my previous comments, but I often end up back on your post and I suspect others might as well... so here's some extra tips...

The use of ;version= is getting deprecated and you should favor of the java_version instead attribute (see [1] for Java 6 and [2] for Java 7).

[1] http://docs.oracle.com/javase/6/docs/technotes/guides/plugin/developer_guide/using_tags.html
[2] http://docs.oracle.com/javase/7/docs/technotes/guides/plugin/developer_guide/using_tags.html
Klaus Reimer at 2013-01-21 16:12
@lo: Can't find any information about this deprecation in these two pages you mentioned. java_version isn't even mentioned once there.
lo at 2013-01-22 18:17
@Klaus Reimer: right, sorry about that.

The original announcement was in 6u10, and noted here:

http://www.oracle.com/technetwork/java/javase/index-141751.html#JPI_VERSION

It's a bit tricky to know what's current or not indeed, as many documents are not up to date since the move to Oracle (for instance, many tutorial pages that link to example code snippets still link to *.sun.com pages). In fact, the link in this very message also suffers from crappy formatting in some sections since the move to Oracle.
nagaraj at 2013-03-19 10:49
Hi Dear i downloaded your code and i am getting Class not found exception com.github.kayahr.applettest.AppletTest,

Please help i am trying from many days

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.