FULL PRODUCT VERSION :
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Server VM (build 20.1-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Reproduced on:
1) Linux 2.6.35-30-generic #56-Ubuntu SMP Mon Jul 11 20:00:22 UTC 2011 i686 GNU/Linux
2) (Mac OS X) Darwin Kernel Version 11.0.0
A DESCRIPTION OF THE PROBLEM :
In this method:
public Iterable<Unit> all() {
final Unit[] units = new Unit[] {new Unit()};
final Ref<Integer> count = new Ref<Integer>(0);
return new Iterable<Unit>() {
@Override
public Iterator<Unit> iterator() {
return new Iterator<Unit>() {
@Override
public boolean hasNext() {
return false;
}
@Override
public Unit next() {
System.out.println("HERE I AM");
// this next line is the offending line - even though this code is NEVER executed!
// it has to do with the reference to units[count.t++]...
System.out.println(units[count.t++]);
return null;
}
@Override
public void remove() {
}
};
}
};
}
... the call to next() never gets calls but the java runtime will fail with a VerifyError because of the line: units[count.t++].
Any changes to the construct will make the runtime work.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Here is the source:
package sandbox;
import java.util.Iterator;
import org.junit.Test;
public class UnitTest {
/**
* works all the time
*/
@Test
public void sanity() {
final Ref<Integer> count = new Ref<Integer>(0);
for (Unit user : new Iterable<Unit>() {
@Override
public Iterator<Unit> iterator() {
return new Iterator<Unit>() {
@Override
public boolean hasNext() {
return false;
}
@Override
public Unit next() {
System.out.println(count.t++);
return null;
}
@Override
public void remove() {
}
};
};
}) {
System.out.println(user);
}
}
/**
* Doesn't work when executed through maven (on mac ox X as well as Ubuntu
* 10.10; jdk 1.6.0_26.)
*
* ... but works when run through Eclipse
*
* strangeJdk16Issue(sandbox.FileStorageTest): (class:
* sandbox/FileStorageTest$2$1, method: next signature: ()Lsandbox/Unit;)
* Incompatible object argument for function call
*
* seems to be related to the remove() call to deleteRecursive()
*/
@Test
public void strangeJdk16Issue() throws Exception {
for (Unit unit : all()) {
System.out.println(unit);
}
}
public Iterable<Unit> all() {
final Unit[] units = new Unit[] { new Unit() };
final Ref<Integer> count = new Ref<Integer>(0);
return new Iterable<Unit>() {
@Override
public Iterator<Unit> iterator() {
return new Iterator<Unit>() {
@Override
public boolean hasNext() {
return false;
}
@Override
public Unit next() {
System.out.println("HERE I AM");
// this next line is the offending line - even though this code is
// NEVER executed!
// it has to do with the reference to units[count.t++]...
System.out.println(units[count.t++]);
return null;
}
@Override
public void remove() {
}
};
}
};
}
private static class Unit {
}
public class Ref<T> {
public T t;
public Ref(T t) {
this.t = t;
}
public Ref() {
}
}
}
2. I would suggest creating a maven project to simplify the execution; here is my pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sandbox</groupId>
<artifactId>jdk16-issue</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>jdk16-issue</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<!--plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>1.6</version>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<compilerVersion>1.6</compilerVersion>
<source>1.6</source>
<target>1.6</target>
<testSource>1.6</testSource>
<testTarget>1.6</testTarget>
<compilerArguments>
<verbose/>
</compilerArguments>
</configuration>
</plugin>
<!--plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<systemProperties>
</systemProperties>
</configuration>
</plugin-->
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
3. mvn clean install
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
-------------------------------------------------------------------------------
Test set: sandbox.UnitTest
-------------------------------------------------------------------------------
Tests run: 2, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.022 sec <<< FAILURE!
strangeJdk16Issue(sandbox.UnitTest) Time elapsed: 0.003 sec <<< ERROR!
java.lang.VerifyError: (class: sandbox/UnitTest$2$1, method: next signature: ()Lsandbox/UnitTest$Unit;) Incompatible object argument for function call
at sandbox.UnitTest$2.iterator(UnitTest.java:66)
at sandbox.UnitTest.strangeJdk16Issue(UnitTest.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345)
at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009)
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER SUBMITTED WORKAROUND :
Interestingly the problem does not show up when the testcase is run from Eclipse.
I compared the compiled classes between eclipse and maven and there are differences but I wasn't able to discern the way eclipse compiled the code.
Regardless, there seems to be a bug in either javac or java.
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Server VM (build 20.1-b02, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Reproduced on:
1) Linux 2.6.35-30-generic #56-Ubuntu SMP Mon Jul 11 20:00:22 UTC 2011 i686 GNU/Linux
2) (Mac OS X) Darwin Kernel Version 11.0.0
A DESCRIPTION OF THE PROBLEM :
In this method:
public Iterable<Unit> all() {
final Unit[] units = new Unit[] {new Unit()};
final Ref<Integer> count = new Ref<Integer>(0);
return new Iterable<Unit>() {
@Override
public Iterator<Unit> iterator() {
return new Iterator<Unit>() {
@Override
public boolean hasNext() {
return false;
}
@Override
public Unit next() {
System.out.println("HERE I AM");
// this next line is the offending line - even though this code is NEVER executed!
// it has to do with the reference to units[count.t++]...
System.out.println(units[count.t++]);
return null;
}
@Override
public void remove() {
}
};
}
};
}
... the call to next() never gets calls but the java runtime will fail with a VerifyError because of the line: units[count.t++].
Any changes to the construct will make the runtime work.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Here is the source:
package sandbox;
import java.util.Iterator;
import org.junit.Test;
public class UnitTest {
/**
* works all the time
*/
@Test
public void sanity() {
final Ref<Integer> count = new Ref<Integer>(0);
for (Unit user : new Iterable<Unit>() {
@Override
public Iterator<Unit> iterator() {
return new Iterator<Unit>() {
@Override
public boolean hasNext() {
return false;
}
@Override
public Unit next() {
System.out.println(count.t++);
return null;
}
@Override
public void remove() {
}
};
};
}) {
System.out.println(user);
}
}
/**
* Doesn't work when executed through maven (on mac ox X as well as Ubuntu
* 10.10; jdk 1.6.0_26.)
*
* ... but works when run through Eclipse
*
* strangeJdk16Issue(sandbox.FileStorageTest): (class:
* sandbox/FileStorageTest$2$1, method: next signature: ()Lsandbox/Unit;)
* Incompatible object argument for function call
*
* seems to be related to the remove() call to deleteRecursive()
*/
@Test
public void strangeJdk16Issue() throws Exception {
for (Unit unit : all()) {
System.out.println(unit);
}
}
public Iterable<Unit> all() {
final Unit[] units = new Unit[] { new Unit() };
final Ref<Integer> count = new Ref<Integer>(0);
return new Iterable<Unit>() {
@Override
public Iterator<Unit> iterator() {
return new Iterator<Unit>() {
@Override
public boolean hasNext() {
return false;
}
@Override
public Unit next() {
System.out.println("HERE I AM");
// this next line is the offending line - even though this code is
// NEVER executed!
// it has to do with the reference to units[count.t++]...
System.out.println(units[count.t++]);
return null;
}
@Override
public void remove() {
}
};
}
};
}
private static class Unit {
}
public class Ref<T> {
public T t;
public Ref(T t) {
this.t = t;
}
public Ref() {
}
}
}
2. I would suggest creating a maven project to simplify the execution; here is my pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sandbox</groupId>
<artifactId>jdk16-issue</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>jdk16-issue</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<!--plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireJavaVersion>
<version>1.6</version>
</requireJavaVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<compilerVersion>1.6</compilerVersion>
<source>1.6</source>
<target>1.6</target>
<testSource>1.6</testSource>
<testTarget>1.6</testTarget>
<compilerArguments>
<verbose/>
</compilerArguments>
</configuration>
</plugin>
<!--plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<systemProperties>
</systemProperties>
</configuration>
</plugin-->
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
3. mvn clean install
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
-------------------------------------------------------------------------------
Test set: sandbox.UnitTest
-------------------------------------------------------------------------------
Tests run: 2, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.022 sec <<< FAILURE!
strangeJdk16Issue(sandbox.UnitTest) Time elapsed: 0.003 sec <<< ERROR!
java.lang.VerifyError: (class: sandbox/UnitTest$2$1, method: next signature: ()Lsandbox/UnitTest$Unit;) Incompatible object argument for function call
at sandbox.UnitTest$2.iterator(UnitTest.java:66)
at sandbox.UnitTest.strangeJdk16Issue(UnitTest.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345)
at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009)
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER SUBMITTED WORKAROUND :
Interestingly the problem does not show up when the testcase is run from Eclipse.
I compared the compiled classes between eclipse and maven and there are differences but I wasn't able to discern the way eclipse compiled the code.
Regardless, there seems to be a bug in either javac or java.
- duplicates
-
JDK-6614974 javac successfully compiles code that throws java.lang.VerifyError when run
-
- Closed
-