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

Invocable.getInterface() works incorrectly if interface has default methods

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P3
    • 9
    • 8u20
    • core-libs
    • b02
    • generic
    • generic

    Backports

      Description

        FULL PRODUCT VERSION :
        java version "1.8.0-ea"
        Java(TM) SE Runtime Environment (build 1.8.0-ea-b121)
        Java HotSpot(TM) 64-Bit Server VM (build 25.0-b63, mixed mode)

        A DESCRIPTION OF THE PROBLEM :
        According to the specification, javax.script.Invocable.getInterface() returns null if the script does not implement every method defined in the specified interface. Surprisingly, this is also true for any default methods defined in the interface.

        The javadoc of getInterface() does not speak about default methods, but common sense suggests that behavior should resemble that of ordinary Java classes implementing the interface.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        foo
        bar
        foo 2
        default bar
        ACTUAL -
        foo
        bar
        [i2 == null -> NPE thrown]

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import javax.script.*;

        public class Test {
            public static void main(String[] args) throws Exception {
                ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
                Invocable invocable = (Invocable) engine;

                Object o1 = engine.eval("({ foo: function() { return 'foo'; }, bar: function() { return 'bar'; } });");
                I i1 = invocable.getInterface(o1, I.class);
                Object o2 = engine.eval("({ foo: function() { return 'foo 2'; } });");
                I i2 = invocable.getInterface(o2, I.class);

                System.out.println(i1.foo());
                System.out.println(i1.bar());
                System.out.println(i2.foo());
                System.out.println(i2.bar());
            }

            public static interface I {
                String foo();

                default String bar() {
                    return "default bar";
                }
            }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        Don't use default methods together with Invocable.getInterface().

        Attachments

          Issue Links

            Activity

              People

                sundar Sundararajan Athijegannathan
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: