Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java debugger can't call some default method implementations

I'm coding in IntelliJ IDEA. When debugging my application, I can't use some default method implementations in Watches.

Here is a condensed example:

public class Friendship {
    interface Friend {
        default void sayHiTo(Friend friend) {
            System.out.println("Hi, " + friend.hashCode());
        }

        default int amountOfHands() {
            return 2;
        }
    }

    public static class BasicFriend implements Friend {

        int numberOfFaces() {
            return 1;
        }
    }

    public static void main(String[] args) {
        System.out.println("Put a breakpoint here");
    }
}

In main() method I put a breakpoint and set up three watches:

// Default interface method with dependency
new BasicFriend().sayHiTo(new BasicFriend())

// Default interface method without dependency
new BasicFriend().amountOfHands()

// Class method
new BasicFriend().numberOfFaces()

The first watch throws NoSuchMethodException complaining that method Friendship$BasicFriend.sayHiTo() doesn't exist.

The second watch runs successfully, but strangely it reports a boxed object {java.lang.Integer@537} "2" instead of just a primitive 2.

The third watch reports a primitive 1, just as expected.

Why is the first watch not working? Is this a bug? Is this actually IDE related? Is it because of some conceptual flaw of default methods? Should it be working as I want it to in the first place? Is the strange result of the second watch somehow related to the issue in the first watch?

like image 777
gvlasov Avatar asked May 04 '15 17:05

gvlasov


People also ask

What is stepover in IntelliJ?

Step overSteps over the current line of code and takes you to the next line even if the highlighted line has method calls in it. The implementation of the methods is skipped, and you move straight to the next line of the caller method. Click the Step Over button. or press F8 .

How to skip debug point in IntelliJ?

Ctrl + F8 (Mac: Cmd + F8) Toggle breakpoint.

How many default and static methods can an interface have?

We can have any number of static methods in the interface. From Java 8, An interface can contain default, static, abstract and non-abstract methods.

What Action is performed by the step out key control?

Step Out command Shift+F11 that is also available in the Run menu and in the Debug window. The debugger will execute the remaining lines of the function by itself and set the execution pointer at the statement following the function call.


1 Answers

Prior to JDK 8u40, default and static interface methods were not supported by JDI (Java Debugger Interface), JDWP (Java Debugger Wire Protocol) and JDB (the standard Java debugger). This is bug JDK-8042123, which is recorded as fixed in 8u40 and a corresponding blurb appears in the 8u40 release notes.

Update to 8u40 or later to fix this issue, at least on the JDK side.

From the bug description, it looks like debugger-side changes are also required, to avoid casting com.sun.jdi.InterfaceType objects to com.sun.jdi.ClassType, but instead call InterfaceType.invokeMethod() directly.

In the specific case of IntelliJ, Suseika confirmed in a comment that 14.1.2 has mostly fixed the issue (except the unexpected boxing), though Mike Kobit still experiences this problem on that version with a ClassCastException suggestive of the incorrect cast above.

like image 188
Jeffrey Bosboom Avatar answered Oct 04 '22 11:10

Jeffrey Bosboom