Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8042696

Existing Java method cannot be called from JavaScript in IE

    XMLWordPrintable

Details

    • b28
    • windows_7

    Backports

      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.

        Attachments

          Issue Links

            Activity

              People

                alitvinov Anton Litvinov (Inactive)
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: