views:

943

answers:

4

I am getting an error that is only reproducible in Firefox.
In IE, it always works.

I have an ASP.NET application that targets an applet. For most functionality, it works great, but when I run one function (a function that does a lot of different things), the methods on the java applet seems to be unavailable! When I call any functions on the java applet from Javascript code, I get the error : myApplet.myFunction is not a function .

After this has happened, I get the same error for everything that calls functions on the applet, also functionality that worked prior to this state.

The applet is not unloaded or crashed, which is proved by that the interactive functions in the applet still works. But if the applet calls a javascript function on the page that calls back to the applet, I get the same error!

Sometimes it works when I repeat the action several times.

This only happens on the public version of the web application. Not in my local web app that runs on development machine. The main difference is that the public one use login access.

Can anyone give me hint of what can be causing this?

To summairize whats happens: When I run a particular bit of javascript code, the API against the java applet becomes unabailable (Error: myApplet.myFunction is not a function).

Here is the function that causes this buggy state of the applet:

function ParseAndZoomToAddress (objString) {
 var mapFrame

 eval("var objArray = new Array(" + objString + ")")
 if (objArray.length > 0) {
  mapFrame = window.frames[0].frames['mapFrame']
  if(!mapFrame) alert('mapFrame is null!')
  else window.status = 'mapFrame is OK!'
  var center_x = 0
  var center_y = 0
  if(objArray.length == 1) {
   var rExp1 = /[G-P]/g
   var rExp2 = /[Q-Z]/g
   eval("var coordArray = new Array(" + objArray[0].replace(rExp1, '0x').replace(rExp2, ',0x') + ")")
   if(coordArray.length == 2){
    center_x = coordArray[0]
    center_y = coordArray[1]
   }else{
    alert("Invalid ID " + objArray[0])
   }
  }else{
   var center_x = objArray[1]
   var center_y = objArray[2]
  }
  var objZoomScale = '2000' // document.SearchForm.Scale.value
  var scale = mapFrame.m_yur - mapFrame.m_yll
  if (objZoomScale != "") {
   scale = ScaleToMeter(parseInt(objZoomScale),mapFrame.m_image_width)
  }
  var xll = center_x - (scale / 2.0)
  var yll = center_y - 10
  var xur = xll + scale
  var yur = center_y + 10
  center_x = (xll + xur) / 2.0
  center_y = (yll + yur) / 2.0
  center_x = Math.round(center_x * 1000) / 1000
  center_y = Math.round(center_y * 1000) / 1000
  mapFrame.ResetClipPolygon() //This calls applet methods
  var lCenterSymbol = '5024,40,85,x,y,5'
  var rExp = /x/gi
  lCenterSymbol = lCenterSymbol.replace(rExp,center_x)
  rExp = /y/gi
  lCenterSymbol = lCenterSymbol.replace(rExp,center_y)
  mapFrame.parent.m_CenterSymbolString = lCenterSymbol
  mapFrame.ResetClipPolygon() //This calls applet methods
  mapFrame.previewVisible()
  mapFrame.mapVisible()
  mapFrame.setMove(false) //This calls applet methods
  mapFrame.ZoomToArea(xll, yll, xur, yur) //This calls applet methods
  mapFrame.parent.m_CenterSymbolString = ""
 }
}

Additionaly I can say that the applet is defined by the <applet> tag.

The applet is located inside a <div> tag that is hidden in javascript with style.display='none' and shown again with style.display='block'. This is done during the 2 lines:

  mapFrame.previewVisible()
  mapFrame.mapVisible()

I don't know if this is the problem, but these function are called elsewhere as well where it doesn't cause this, but it might be combination of things.

I am happy to get hint's that will help me solve this, not an absolute solution.

I will accept the best hint as the answer.

A: 

This post seems to have similar problem. They claim they fixed some HTML syntactic error and then it worked in Firefox.

Superfilin
+1  A: 

Perhaps this is a timing issue. It could happen that the Firefox engine tries to execute the javascript code before the java applet has been properly loaded. To verify this add a delay before accessing the applet in javascript code. Even better use a try-catch block for your call and wrap it in a for-loop. If the call is successful exit the loop, otherwise add a delay and retry.

Edit: Based on your edits it seems that there isn't a timing issue. Since your javascript function is quite big, I would try to locate, where the problem first appears. Create a dummy applet method and call it inside your javascript method at various places. Find out after which statement the problem first appears. Also, if you haven't done that already, install Firebug and watch out for javascript errors.

kgiannakakis
What about other functions that actually worked before...) Could it be that when the applet interface fails once, the loading of the API is somehow aborted, and left in a buggy state?
awe
What you mean by working before? You call some applet methods successfully, then call some javascript code, then you try to call another applet method and it fails? In that case timing has probably nothing to do with the problem. It wouldn't hurt however to try what I have suggested.
kgiannakakis
After I call this javascript none of the applet methods work. Before I call it, all the applet methods work. I will try it, but it will take some time to be able to test, since it is only reproducible in the live app on the customer web server, not in my debug environment...
awe
You have helped me in the right direction. Thank You. See my answer for details on how it was fixed: http://stackoverflow.com/questions/1536814/java-error-in-firefox-myapplet-myfunction-is-not-a-function/1571021#1571021
awe
A: 

I was suddenly able to reproduce it in my development environment, so it was easier to locate the problem. The problem was related to hiding/showing as I suspected, but I'm still not sure why it was a problem. It was probably some sort of timing issues as noted by kgiannakakis, so will credit him with the bounty reward.

The problem disappeared when commenting out these two lines:

mapFrame.previewVisible(); // appletDiv.style.display="none"
mapFrame.mapVisible();     // appletDiv.style.display="block"

The comment at end is basically what is done inside those functions with the div that contains the applet.


So far, so good.

The intention with the Visible functions are originally switching 2 tabs where one of them displays the applet (mapVisible), and the other displays a static image (previewVisible). If I click the preview tab, that basically runs previewVisible(), the appletDiv is hidden. If I then run my big nasty function (ParseAndZoomToAddress) then I get the error again, but this time it is somewhat expected, since the applet is hidden (and obviously FireFox does not like to work with hidden applets..).

Then I remember why I included these calls inside the ParseAndZoomToAddress function: I have to make sure the applet is visible before accessing it! So I try to re-introduce the call to mapFrame.mapVisible(), and guess what - it works! Even if the applet was hidden, it is available after the call to mapFrame.mapVisible().


Anyone have a conclusion to this?

My theory is that it causes problems to unload and reload the applet so close together in the same javascript function.

awe
A: 

I came here through a search, as I had exactly the same problem with "myApplet.myFunction is not a function" in Firefox (not MSIE), on web pages that I knew I had not changed for years and that I knew had worked fine before in Firefox. As it turns out, in my case the culprit is just having the Google Translate Tools Javascript code described at

http://translate.google.com/translate%5Ftools?hl=en&amp;layout=1&amp;eotf=1&amp;sl=bg&amp;tl=en

After I had removed that snippet from my included Javascript file (included at the bottom of my applet page), myApplet.myFunction worked fine again! It also fixed the mysterious problem that my applet would not always load when loading the web page. Maybe Google Translate Tools under the hood also fiddles with style.display or similar, but I did not further dig into that. I suspect that many others who use Google Translate Tools on a Java applet page with Javascript controls are similarly affected.

Peter Meijer