3

LiveConnect is a Mozilla technology that bridges Java and JavaScript. Amazingly, they've started maintaining it again for recent versions of Firefox. In Firefox I can write e.g.

var d = new java.util.Date();

or use the Packages. namespace if it's not a java.something

var d = new Packages.java.util.Date();

or I could go crazy and call a factory method in swing

Packages.javax.swing.Box.createVerticalBox();

easily instantiating any Java object. Is there an equivalent that works in ie?

joeforker
  • 40,459
  • 37
  • 151
  • 246
  • 2
    "Java has as much in common with JavaScript as a car has with a carpet." If you can do this in Firefox, it's leaking abstractions badly, not to mention allowing external webpage to run locally executed code on visitor's computer. – Esko Aug 18 '09 at 19:17
  • Of course I tried it, and of course it doesn't work this way in ie. It should be obvious that the question means 'what is the syntax for doing the same thing in ie'. – joeforker Aug 18 '09 at 19:38
  • @Esko: If it is a leaky abstraction, then Firefox is leaking all over computers everywhere. The security model protects you from doing silly things like being able to access the local file system: `var f = new java.io.File("test.txt"); document.write(f.exists());` results in: `Error: uncaught exception: Error calling method on NPObject! [plugin exception: java.security.AccessControlException: access denied (java.io.FilePermission test.txt read)].` However, `var s = new java.lang.StringBuilder("Hello"); s.append(", World!"); document.write(s);` works just fine: `Hello, World!` – Grant Wagner Aug 18 '09 at 19:48
  • @joeforker: I really wished this worked everywhere. Imagine having the entire Java class library (minus anything forbidden by access control) at your disposal in client-side JavaScript! – Grant Wagner Aug 18 '09 at 20:01
  • @Grant As of JDK 6 update 10, applets *have* that .Packages object exposing the entire Java class library, even in ie. Who knew? – joeforker Aug 19 '09 at 04:09

6 Answers6

5

What you can do in Internet Explorer is load an applet into the page which exposes methods that do the things you want to do. You get a reference to the applet, then invoke methods on that reference.

<applet id="myAppletId" name="myAppletName" ...>

var applet = document.getElementById('myAppletId');
var d = applet.getDateFromApplet();

In your applet you'd need a public method getDateFromApplet() that returns a java.util.Date.

Note that what I present should work, but it has been years since I did this (it worked in NS4, 6 and IE 4+ at the time). I didn't use getElementById() however, I used var applet = document.myAppletName;.

The other complication to this is that if you want this to execute on page load, the applet will almost certainly not be ready, which requires code something like:

function checkApplets() {
    var da = document.applets; // document.getElementsByName('applet');?

    if (da.length > 0) {
        for (var ii = da.length; ii-- > 0;) {
            if (!da[ii].isActive()) {
                window.timerId = setTimeout(checkApplets, 250);
                return;
            }
        }

        if (window.timerId) {
            clearTimeout(window.timerId);
        }
    }

    window.appletsLoaded = true;
}

Lastly, it might (should) be possible to do this with the <object> tag, but as I said, it has been years since I needed to interact with a Java applet in this way from client-side JavaScript, so I haven't tested it.

Grant Wagner
  • 25,263
  • 7
  • 54
  • 64
  • The applet should just call a method on the page when it is ready? – joeforker Aug 18 '09 at 20:00
  • How about if "the thing I want to do" is the Rhino eval() statement bundled with Java 6 :-) – joeforker Aug 18 '09 at 20:24
  • @joeforker: 1) I'm not sure the applet can call a method on the page. You have to wait for the applet to be ready, then call into it from JavaScript. 2) Yes, the applet could potentially have a single public `do()` or `eval()` method that you just pass Java as plain text to and have it execute inside the applet on the browser. – Grant Wagner Aug 18 '09 at 20:58
  • If JavaScript tries to call applet methods before it's ready, the plugin will make the call wait until it's ready. – joeforker Aug 19 '09 at 04:11
  • Still works, years ago MS released a javascript/java applet rpc proxy, called MSRS (microsoft remote scripting). I had to mantain a web application built using MSRS, and works well in IE7. The javascript library calls a public method of the java class, so I think your approach to this question will do the job too. http://www.ashleyit.com/rs/ – Rodrigo Aug 19 '09 at 04:41
4

You are using LiveConnect which is a Mozilla-specific JavaScript/Java bridge. It is not supported in other browsers.

JacquesB
  • 41,662
  • 13
  • 71
  • 86
2

You could make the properties of your objects available through a JSON response from your servlet in JAVA? Since JS can readily use JSON and it is light weight it makes for an easy way to crate JS Objects from your Java Objects.

Also look at the Rhino JavaScript engine and making Java resources available from JavaScript. https://developer.mozilla.org/en-US/docs/Rhino_documentation

fungi
  • 21
  • 1
1

As far as I know, I don't think this is possible - Java and Javascript are completely different. It just so happens that the JS API contains a Date object, as does the Java API.

Edit: The Java Scripting API (http://java.sun.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.html#jsengine) seems to be the closest you can get to what you're trying to do.

tw39124
  • 9,103
  • 2
  • 20
  • 14
  • @Tom: His code is actually creating a Java `Date` and referencing it from client-side JavaScript. Consider: `var r = new java.util.Random(); document.write(r.nextBoolean() + ';' + r.nextDouble() + ';' + r.nextFloat() + ';' + r.nextGaussian() + ';' + r.nextInt() + ';' + r.nextLong());` Client-side JavaScript doesn't have a `Random()` object, and it certainly doesn't have any `next*()` methods available. – Grant Wagner Aug 18 '09 at 19:58
1

As of Java 1.6 update 10, the Inter-Language LiveConnect Bridge attaches a Packages object to applets within the page, just like the Packages object available in Firefox. So in a page with at least one applet, even in Internet Explorer,

new document.applets[0].Packages.java.util.Date().toString();

returns the current date. It's also possible to register new converters for convenient access to non-Java languages running in the Java virtual machine. Of course JavaFX implements such a bridge.

It's not supposed to be necessary to wait for the applet to load before calling it from JavaScript but it's probably a good idea. The Java plugin will make JavaScript wait until the applet finishes loading or has an error. It is possible for the applet to call JavaScript in the web page as soon as Applet.init() is called.

joeforker
  • 40,459
  • 37
  • 151
  • 246
0

You could possibly use DWR or some other reverse ajax library that will allow you to create Java objects on the server side via Javascript objects.

jconlin
  • 3,806
  • 6
  • 31
  • 32