Default method returns true for a while, and then returns false? (Possible JVM bug)

JavaInheritanceInterfaceJava 8

Java Problem Overview


I have an issue with the following code, which I isolated to the most closed form, I am using Java 8, which is almost ready for launch (18 March 2014), so I expect no serious issues in the implementation itself, so it may/must be my own code:

Note: The code is written in Java 8, which has all kinds of new features, including default method implementation in interfaces.

public abstract class Drawable implements DrawableInterface {    

}

interface DrawableInterface {
    default public boolean isShadowReceiver() {
        return false;
    }

    default public boolean isShadowCaster() {
        return false;
    }
}

public interface ShadowDrawable extends DrawableInterface {
    @Override
    default public boolean isShadowReceiver() {
        return true;
    }

    @Override
    default public boolean isShadowCaster() {
        return true;
    }
}

public class Box extends Drawable implements ShadowDrawable {

}

public class IsolatedBug {
    private final Box box;

    private final List<Drawable> drawables;

    public IsolatedBug() {
        this.box = new Box();
        this.drawables = new ArrayList<>();

        drawables.add(box);
        drawables.forEach(drawable -> System.out.println(drawable + " C=" + drawable.isShadowCaster() + "/R=" + drawable.isShadowReceiver()));
    }

    private void init() throws InterruptedException {
        while (true) {
            drawables.forEach(drawable -> System.out.println(drawable + " C=" + drawable.isShadowCaster() + "/R=" + drawable.isShadowReceiver()));
            Thread.sleep(100);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new IsolatedBug().init();
    }
}

The code in itself may not make most sense, but that is because I have stripped a load of other irrelevant methods.

However, when you observe the output, you see something strange, at a certain point, for me personally after 30 seconds, I see the following:

>isolatedbug.Box@5acf9800 C=true/R=true
isolatedbug.Box@5acf9800 C=true/R=true
isolatedbug.Box@5acf9800 C=true/R=true
isolatedbug.Box@5acf9800 C=true/R=true
isolatedbug.Box@5acf9800 C=false/R=false
isolatedbug.Box@5acf9800 C=false/R=false
isolatedbug.Box@5acf9800 C=false/R=false
isolatedbug.Box@5acf9800 C=false/R=false
isolatedbug.Box@5acf9800 C=false/R=false
isolatedbug.Box@5acf9800 C=false/R=false

The time when it switches from true to false, seems to depend on the number of calls the method, as with longer sleeps in between, it takes longer to switch.

I am running this, for full information on Windows 8 64-bit, with as java -version:

>java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b129)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b69, mixed mode)

Can anyone explain to me what is going on?
I'd also appreciate if others with Java 8 -any build-, could run and see if they have the same issue.

Some more information after using this code:

  Properties p = System.getProperties();
  p.list(System.out);

Output:

-- listing properties --
java.runtime.name=Java(TM) SE Runtime Environment
sun.boot.library.path=C:\Program Files\Java\jdk1.8.0\jre\bin
java.vm.version=25.0-b69
java.vm.vendor=Oracle Corporation
java.vendor.url=http://java.oracle.com/
path.separator=;
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
file.encoding.pkg=sun.io
user.script=
user.country=NL
sun.java.launcher=SUN_STANDARD
sun.os.patch.level=
java.vm.specification.name=Java Virtual Machine Specification
user.dir=C:\Users\Frank\Dropbox\NetbeansProjec...
java.runtime.version=1.8.0-b129
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs=C:\Program Files\Java\jdk1.8.0\jre\li...
os.arch=amd64
java.io.tmpdir=C:\Users\Frank\AppData\Local\Temp\
line.separator=

java.vm.specification.vendor=Oracle Corporation
user.variant=
os.name=Windows 8.1
sun.jnu.encoding=Cp1252
java.library.path=C:\Program Files\Java\jdk1.8.0\bin;C:...
java.specification.name=Java Platform API Specification
java.class.version=52.0
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
os.version=6.3
user.home=C:\Users\Frank
user.timezone=
java.awt.printerjob=sun.awt.windows.WPrinterJob
file.encoding=UTF-8
java.specification.version=1.8
user.name=Beheerder
java.class.path=C:\Users\Frank\Dropbox\NetbeansProjec...
java.vm.specification.version=1.8
sun.arch.data.model=64
java.home=C:\Program Files\Java\jdk1.8.0\jre
sun.java.command=isolatedbug.IsolatedBug
java.specification.vendor=Oracle Corporation
user.language=nl
awt.toolkit=sun.awt.windows.WToolkit
java.vm.info=mixed mode
java.version=1.8.0
java.ext.dirs=C:\Program Files\Java\jdk1.8.0\jre\li...
sun.boot.class.path=C:\Program Files\Java\jdk1.8.0\jre\li...
java.vendor=Oracle Corporation
file.separator=\
java.vendor.url.bug=http://bugreport.sun.com/bugreport/
sun.cpu.endian=little
sun.io.unicode.encoding=UnicodeLittle
sun.desktop=windows
sun.cpu.isalist=amd64

I have also checked the -Xint VM option, when this has been used, it returns true as expected.

So the conclusion seems to be that in my particular use case, the interpreted and JIT compiled/inlined variants of the code are not the same and hence it is a possibility that after the interpreted code is compiled it switches from interpreted to compiled and thus clarifying the switch in output.

Adding the -Xint option to the actual program in which the bug occured, has also fixed the issue there.

The official bug report has been accepted: JIRA Bug JDK-8036100

Java Solutions


Solution 1 - Java

This is a known bug in Java8.

See this Jira: CHA ignores default methods during analysis leading to incorrect code generation

This blog entry is enlightening....

Update / Summary:


Previous Notes

I have reproduced this issue with:

Claims that this issue is resolved in b127 are confusing since I see it clearly in b129 (unless I am confused about the JVM version conventions...)

> C:\Java8\jdk-1.8.0_01\bin>java -version > java version "1.8.0" > Java(TM) SE Runtime Environment (build 1.8.0-b129) > Java HotSpot(TM) 64-Bit Server VM (build 25.0-b69, mixed mode) >
> C:\Java8\jdk-1.8.0_01\bin>

Adding System.out.println(System.getProperties());

> { > java.runtime.name=Java(TM) SE Runtime Environment, > java.runtime.version=1.8.0-b129, > java.vm.specification.name=Java Virtual Machine Specification, > java.vm.name=Java HotSpot(TM) 64-Bit Server VM, > java.vm.version=25.0-b69, > java.vm.vendor=Oracle Corporation, > java.vendor.url=http://java.oracle.com/, > java.vm.specification.version=1.8, > java.specification.name=Java Platform API Specification, > java.specification.version=1.8, > java.specification.vendor=Oracle Corporation, > java.class.version=52.0, > sun.boot.library.path=C:\Java8\jdk-1.8.0_01\jre\bin, > sun.java.launcher=SUN_STANDARD, > sun.os.patch.level=Service Pack 1, > java.endorsed.dirs=C:\Java8\jdk-1.8.0_01\jre\lib\endorsed, > os.arch=amd64, > java.vm.specification.vendor=Oracle Corporation, > os.name=Windows 7, > sun.jnu.encoding=Cp1252, > java.library.path=C:\Java8\jdk-1.8.0_01\bin;......, > sun.management.compiler=HotSpot 64-Bit Tiered Compilers, > os.version=6.1, > file.encoding=UTF-8, > sun.java.command=fromso.IsolatedBug, > java.home=C:\Java8\jdk-1.8.0_01\jre, > sun.arch.data.model=64, > user.language=en, > java.ext.dirs=C:\Java8\jdk-1.8.0_01\jre\lib\ext;C:\windows\Sun\Java\lib\ext, > > sun.boot.class.path=C:\Java8\jdk-1.8.0_01\jre\lib\resources.jar;......, > java.vendor=Oracle Corporation, > file.separator=, > java.vendor.url.bug=http://bugreport.sun.com/bugreport/, > sun.io.unicode.encoding=UnicodeLittle, > sun.cpu.endian=little, > sun.desktop=windows, > sun.cpu.isalist=amd64 > }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionskiwiView Question on Stackoverflow
Solution 1 - JavarolflView Answer on Stackoverflow