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

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

XMLWordPrintable

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

        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().

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

                Created:
                Updated:
                Resolved: