JDK-8042696 : Existing Java method cannot be called from JavaScript in IE
  • Type: Bug
  • Component: deploy
  • Sub-Component: plugin
  • Affected Version: 7u4,7-pool,8-pool,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_7
  • Submitted: 2013-05-31
  • Updated: 2015-01-21
  • Resolved: 2014-07-29
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8 JDK 9
7u76Fixed 8u40Fixed 9 b28Fixed
Description
FULL PRODUCT VERSION :
JDK 9, JDK 8, JDK 7u4, any later release of JDK 7

ADDITIONAL OS VERSION INFORMATION :
MS Windows 7 OS

A DESCRIPTION OF THE PROBLEM :
Given a class with an inner class that implements interface. For example: java.util.Vector.elements() returns an inner class implementation of Enumeration. When JavaScript call is made to invoke a method that does not exist in Java class, but the same method exists in the inner class, then all subsequent JavaScript calls to the inner class method will result in the JavaScript exception "TypeError: <JAVA_METHOD_NAME> is not a function".

Note: this bug does not exist in Mozilla based browsers and only occurs in IE with JRE 7u4+. It has been tested on IE 8 & 10 in both 32 & 64 bit mode.

Two applets are required, since subsequent calls to just one applet after exercising the broken execution will result in the exception always being raised. It appears that the browser/applet bridge maintains a separate reflection cache per applet.

REGRESSION.  Last worked in version 6u45

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
A call to an Applet is made to create a Vector. On the returned Vector object, hasMoreElements() is called - which doesn't exist, and which is described in the message in the first alert popup. Next, a call is made to create an Enumeration from the contents of a Vector. On the returned Enumeration object, hasMoreElements() is called - which does exist, but the same exception message is reported in the second alert popup.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
This is the bug: hasMoreElements() should be present in the Enumeration object returned.

A call to another Applet is made to create an Enumeration from the contents of a Vector first. On the returned Enumeration object, hasMoreElements() is called, and this time the message in the alert popup is as expected - that hasMoreElements() returned false.

ACTUAL -
"TypeError: <JAVA_METHOD_NAME> is not a function"

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
// Save as AppletTest.java

import java.applet.Applet;
import java.util.Enumeration;
import java.util.Vector;

/**
 * Basic Applet to help illustrate a bug found in IE.
 *
 * Found when using JavaScript to call Java Code.
 *
 * @see index.html for further information.
 */
public class AppletTest extends Applet {

  /**
   * Creates an empty Vector.
   *
   * @return The empty Vector.
   */
  public Vector<String> createVector() {
    Vector<String> temp = new Vector<String>();
    return temp;
  }

  /**
   * Creates an empty Enumeration, from the contents of the empty Vector.
   *
   * @return The empty Enumeration.
   */
  public Enumeration<String> createEnumeration() {
    return createVector().elements();
  }

} 

// End AppletTest.java


// Save as index.html
<html>
<head>
<script type= " javascript " >
/**
 * Function called by clicking on the appropriate button on the HTML page.
 *
 * @param showBroken Should the broken approach be executed?
 */
function executeTest(showBroken) {
  if (showBroken) {
    testByCreatingVectorFirst(appletBroken);
  }else {
    testByCreatingEnumerationFirst(appletWorking);
  }
}


/**
 * Tests whether the collectionObj has the function 'hasMoreElements()'
 *
 * @param collectionObj The object to test.
 */
function testCollectionType(collectionObj){
  var msg = collectionObj.getClass().getName() +  "  hasMoreElements?

 "  ;
  try {
    msg += collectionObj.hasMoreElements();
  } catch (ex){
    msg +=  " method doesn't exist:  "  + ex.toString();
  }
  alert(msg);
}

/**
 * Test that shows by creating a Vector object first, followed by creating
 * an Enumeration object, then the Enumeration Object won't have the 'hasMoreElements()' - which it should.
 *
 * @param app The Applet that will create the Vector and Enumeration Objects.
 */
function testByCreatingVectorFirst(app) {
  var vector = app.createVector();
  testCollectionType(vector);
  
  // The returned object should have the 'hasMoreElements()' - but it doesn't.
  var enumeration = app.createEnumeration();
  testCollectionType(enumeration);
}

/**
 * Tests by creating an Enumeration Object - that it will have the 'hasMoreElements()'
 *
 * @param app The Applet that will create the Enumeration Object.
 */
function testByCreatingEnumerationFirst(app) {
  var testEnumeration = app.createEnumeration();
  testCollectionType(testEnumeration);
}
</script>
</head>
<body>
<button onclick= " executeTest(true) " >Broken Execution</button>
  <button onclick= " executeTest(false) " >Working Execution</button>
 
  <!-- An instance of the Applet to use to illustrate the broken execution. -->
  <object type= " application/x-java-applet " 
          name= " appletBroken " 
          id= " appletBroken " >
    <param name= " code "  value= " AppletTest "  />
  </object>
 
  <!-- An instance of the Applet to use to illustrate the working execution. -->
  <object type= " application/x-java-applet " 
          name= " appletWorking " 
          id= " appletWorking " >
    <param name= " code "  value= " AppletTest "  />
  </object>

</body>
</html>

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
This suggests a short term work around: Ensure that the existing method on the inner class is invoked first.
Comments
The modified test case which allowed to reproduce the bug with JRE 9, JRE 8u5, JRE 7u55, JRE 7u4 was attached to the bug as "AppletTest.zip" file.
19-05-2014

The provided test case was modified to make it loadable in the browsers and confirm to requirements of the latest releases of JRE 9, JRE 8, JRE 7. The bug was reproduced with the modified test case on MS Windows OS with Internet Explorer (IE) 8 and JRE 9 b13, JRE 8u5 b13, JRE 7u55 b13, JRE 7u4 b22. The bug could not be reproduced with: - the specified above builds of JRE on Firefox 29. - JRE 7u3 b05 and with IE 8, what proves that this bug appeared in JRE 7u4.
16-05-2014