views:

3484

answers:

3

I have a java applet running in a browser that is calling some javascript functions and expecting a result from theses functions. This is working with the following configurations :

  • Internet Explorer
  • FireFox / Windows
  • Safari / Mac

BUT It's not working with Firefox on MAC OS

The source of the problem seems to be the win.eval calls that always return null. I tested this with Firefox 3.0.6 on a Mac OS X 10.4.11

A bit of code :

JSObject win = (JSObject) JSObject.getWindow(this);
Object exp = win.eval("testfunc()");
System.out.println("exp = " + exp.toString());

This triggers a java.lang.NullPointerException (exp.toString()) statement). The testfunc javascript function just returns true.

I tried with win.call and got the same result.

My applet tag includes the mayscript and scriptable attributes.


I found the answer thanks to Tristan. Testing his solution I created a really simple test that could work and worked my way to find the culprit. I was sure I did my tests with an empty testfunc() that just returned true, but I probably didn't because in that case it DOES work. The real problem here was that the function called a public method of the applet. Liveconnect doesn't seem to be able to handle that case in Firefox Mac.

Let me give you an example :

Java class :

public class MyApplet extends Applet {  
     public int getMyValue() {
         return 5;
     }

     public void somefunction() {
         JSObject win = (JSObject) JSObject.getWindow(this);
         Object exp = win.eval("jsfunc()");
         System.out.println("exp = " + exp.toString());
     }
}

And the javascript code :

function jsfunc() {
    var myApplet = document.getElementById("applet_id");
    return myApplet.getMyValue() + 5;
}

exp will be null in somefunction BECAUSE jsfunc calls the getMyValue() method of the applet. If you remove all calls to properties of the applet you're cool.
To solve my problem I decided to give all the values of the applet that I neeeded as parameters of my javascript function and I'm good now.
That may not be the case always, if the javascript changes the state of the applet ...I was lucky :)

+1  A: 

Would it work via accessing one of the global objects on the screen? Ergo,

In JavaScript:

window.testfunc = function() { //... }

In Applet:

win.eval("window.testfunc()") // or maybe just win.eval("testfunc()")

That would be my experiment. But I've been calling "window.close()" on FF on Mac OS X, and that still works.

Tristan Juricek
Calling the function is not the problem, getting the result back is. With debug statements I can see clearly that the function is executed, but somehow the return value gets lost and I only get "null".
Sébastien Nussbaumer
+1  A: 

I haven't used the applet api in a while but if i recall correctly in order to allow an Applet to cann JS code you should enable the attribute mayscript in your applet tag or a param mayscript in the object tag notation.

For communication in the other way JS to Applet you should also use the scriptable attribute or parameter, for example:

<applet code="..." mayscript="true" />

This allows your applet to use script functions.

<applet code="..." scriptable="true" />
Paulo Lopes
The mayscript and scriptable attributes are necessary indeed. But I already include them in my applet tag, otherwise it wouldn't work at all with other browsers.
Sébastien Nussbaumer
A: 

If you remove all calls to properties of the applet you're cool.

This may happen in other situations as well. I found this page after Googling a similar problem, so I thought I'd add a datapoint. The only difference is that I was using win.call() rather than win.eval().

I had an alert() call in the JavaScript to make sure the call was getting through, and saw what appears to be exactly the same lockup on Firefox 3.0.9, OS X 10.5.6, Java 1.5.0_16. 100% repeatable with Firefox, no problem on Safari (I don't have Windows installed on this box).

When I got rid of the alert() and simply returned a value, the problem went away.

Sooooo... maybe calls into JavaScript time out after a while and simply toss null?