Tuesday, November 18, 2008

Java in Firefox extension hosed again

A full-featured browser, an XUL front end, and the wealth of libraries available in Java makes for a powerful and flexible combination. The browser extension capability of Firefox, along with LiveConnect has been used by at least three extensions:

Most of what I've figured out about using Java from an extension came from Simile's David Huynh. Sadly, development of Piggy Bank has now "quiesced".

I don't know about the others, but Firegoose is hosed by the latest Java 6 update 10. Apparently, Java 6.10 introduces some significant changes into LiveConnect and the Java browser plugin. It's certainly good that Java in the browser is getting some attention, but I wish Java in a Firefox extension was a supported and regression tested use case (see whining here). The fact that it's such an arcane, unsupported and brittle hack is holding back what could otherwise be a nice technique.

Interest in Java in Firefox extensions appears to exist according to these posts in the MozillaZine Extension Development forum:

First Problem: The error I get appears to happen when reflectively instantiating a Java array and looks like this:

Error calling method on NPObject!
[plugin exception: java.lang.IllegalArgumentException: No method
found matching name newInstance and arguments
[com.sun.java.browser.plugin2.liveconnect.v1.JavaNameSpace,
java.lang.Integer]].

Instantiating the array through reflection was, itself, a work-around for another LiveConnect issue with type conversion between Javascript arrays and Java arrays. It's barfing on line 03 below:

// from http://simile.mit.edu/repository/java-firefox-extension/firefox/chrome/content/scripts/browser-overlay.js
_toJavaUrlArray: function(a) {
 var urlArray = java.lang.reflect.Array.newInstance(java.net.URL, a.length);
 for (var i = 0; i < a.length; i++) {
  var url = a[i];
  java.lang.reflect.Array.set(
   urlArray,
   i,
   (typeof url == "string") ? new java.net.URL(url) : url
  );
 }
 return urlArray;
}

Update 1: First problem solved easily enough.

var dummyUrl = new java.net.URL("http://gaggle.systemsbiology.org");
var urlArray = java.lang.reflect.Array.newInstance(dummyUrl.getClass(), a.length);

Now, on to more hideousness:

Error calling method on NPObject!
[plugin exception: java.security.AccessControlException: access denied
(java.lang.RuntimePermission createClassLoader)].

...caused by trying to instantiate a URLClassLoader. The next-generation Java Plug-in, including in update 10, makes changes to the security policy such that calls from Javascript to Java are uniformly treated as untrusted.

Update 2: A Work-around!

A post on the java.net forum has a work-around. You can disable the "next-generation plug-in" through the Java control panel. Under the Advanced tab, open Java Plug-in, deselect Enable the next-generation Java Plug-in, then, restart Firefox. There is a bug filed whose comments seem to suggest that it will be addressed in a future release of the Java Plug-in.

Update 3: According to this thread on java.net, a fix is on the way in Java SE 6 update 12. Thanks, Sun!

More references:

4 comments:

  1. Hi,

    thanks for this very helpful information. In recent times the Javascript Java liveconect bridge changes too often in my opinion.

    Best
    makube

    ReplyDelete
  2. I had been away from this stage of XUL/Java development since August, now returned to it (after glibly accepting updates from Sun) and found the very error:

    Error calling method on NPObject! [plugin exception: java.lang.IllegalArgumentException: No method found matching name newInstance and arguments [com.sun.java.browser.plugin2.liveconnect.v1.JavaNameSpace, java.lang.Integer]]

    Lost about 6-8 hours wondering what the heck I had done to destabilize my code, finally punted and put the error into Google to find you very helpful insight.

    Thank you, thank you! (and thank you Sun for attending to this soon)

    ReplyDelete
  3. thanks a lot for this very useful article, you looks professional with Firefox extensions, and I have a question that I don't know if you may want to receive it over here.

    below is my question:
    I have a firfox extension, which has been built for an academic purposes, and used java with the extension; now any time I modify it, and want to drag drop the xpi, it gives "error because not valid installation package-207" wish you can help me with this, will be very very grateful, feel free to reply on my email.

    --Hiba

    ReplyDelete
  4. @Hiba,

    The format for XPI's is described here:

    https://developer.mozilla.org/en/Building_an_Extension

    In my experience, Firefox can be really sensitive to things like whether you put a slash at the end of a filename in the chrome.manifest file. Do the wrong thing and it's likely to fail silently.

    The best thing to do is follow a working example. Good luck!

    ReplyDelete