Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 526
skiwi Avatar asked Feb 28 '14 13:02

skiwi


1 Answers

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:

  • issue identified before b127, and fixed in b127 ( JDK-8031695 )
  • issue reappeared (or a similar issue appeared) in b129 ( JDK-8036100 )
  • issue has been 'worked around' (disable the optimization that was failing) in b132 ( available here )
  • issue also logged for a 'proper' fix for later ( JDK-8036153 )

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 } 
like image 125
rolfl Avatar answered Sep 29 '22 15:09

rolfl