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

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

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 8u20
    • Fix Version/s: 9
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • Resolved In Build:
      b02
    • CPU:
      generic
    • OS:
      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

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

                  Dates

                  • Created:
                    Updated:
                    Resolved: