Steps to reproduce should be self-explanatory, see below. I am using Linux 2.4.18, glibc 2.3.1.
javac from 1.3.1 up through 1.4.2b18 compiles the first example incorrectly (or at least the VM thinks so). By removing one statement (which will not be executed anyway) javac in 1.4.2b18 (but not 1.4.1 or earlier) compiles it correctly and the VM prints "hello" as it should. Both examples should compile and print "hello" when run, I think.
As far as I am aware, 'x' is definitely assigned by the end of the main try-block, but maybe the JLS says differently. Anyway, javac should either compile it to valid bytecode or give a compilation error. If 'x' is given a dummy initial value of 'null', all is well, so the problem is in the definite assignment.
for i in 1 2; do echo ---$i---; cat TestVerifyError$i.java; for j in /space/jdk1.3.1_03 /space/jdk1.4.0_01 /space/jdk1.4.1_01 /space/jdk1.4.2-beta-b18; do echo $j; $j/bin/javac TestVerifyError$i.java; $j/bin/java -showversion TestVerifyError$i; done; done
---1---
public class TestVerifyError1 {
public static void main(String[] a) {
String x;
try {
x = new String("hello");
} finally {
try {
new String("goodbye");
} catch (RuntimeException e) {
e.printStackTrace();
x = null;
}
}
if (x != null) {
System.out.println(x);
}
}
}
/space/jdk1.3.1_03
java version "1.3.1_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_03-b03)
Java HotSpot(TM) Client VM (build 1.3.1_03-b03, mixed mode)
Exception in thread "main" java.lang.VerifyError: (class: TestVerifyError1, method: main signature: ([Ljava/lang/String;)V) Register 1 contains wrong type
/space/jdk1.4.0_01
java version "1.4.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03)
Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)
Exception in thread "main" java.lang.VerifyError: (class: TestVerifyError1, method: main signature: ([Ljava/lang/String;)V) Register 1 contains wrong type
/space/jdk1.4.1_01
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)
Exception in thread "main" java.lang.VerifyError: (class: TestVerifyError1, method: main signature: ([Ljava/lang/String;)V) Register 1 contains wrong type
/space/jdk1.4.2-beta-b18
java version "1.4.2-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-beta-b18)
Java HotSpot(TM) Client VM (build 1.4.2-beta-b18, mixed mode)
Exception in thread "main" java.lang.VerifyError: (class: TestVerifyError1, method: main signature: ([Ljava/lang/String;)V) Register 1 contains wrong type
---2---
public class TestVerifyError2 {
public static void main(String[] a) {
String x;
try {
x = new String("hello");
} finally {
try {
new String("goodbye");
} catch (RuntimeException e) {
x = null;
}
}
if (x != null) {
System.out.println(x);
}
}
}
/space/jdk1.3.1_03
java version "1.3.1_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_03-b03)
Java HotSpot(TM) Client VM (build 1.3.1_03-b03, mixed mode)
Exception in thread "main" java.lang.VerifyError: (class: TestVerifyError2, method: main signature: ([Ljava/lang/String;)V) Register 1 contains wrong type
/space/jdk1.4.0_01
java version "1.4.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03)
Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)
Exception in thread "main" java.lang.VerifyError: (class: TestVerifyError2, method: main signature: ([Ljava/lang/String;)V) Register 1 contains wrong type
/space/jdk1.4.1_01
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)
Exception in thread "main" java.lang.VerifyError: (class: TestVerifyError2, method: main signature: ([Ljava/lang/String;)V) Register 1 contains wrong type
/space/jdk1.4.2-beta-b18
java version "1.4.2-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-beta-b18)
Java HotSpot(TM) Client VM (build 1.4.2-beta-b18, mixed mode)
hello
###@###.### 2003-03-24
###@###.### 2003-03-24
javac from 1.3.1 up through 1.4.2b18 compiles the first example incorrectly (or at least the VM thinks so). By removing one statement (which will not be executed anyway) javac in 1.4.2b18 (but not 1.4.1 or earlier) compiles it correctly and the VM prints "hello" as it should. Both examples should compile and print "hello" when run, I think.
As far as I am aware, 'x' is definitely assigned by the end of the main try-block, but maybe the JLS says differently. Anyway, javac should either compile it to valid bytecode or give a compilation error. If 'x' is given a dummy initial value of 'null', all is well, so the problem is in the definite assignment.
for i in 1 2; do echo ---$i---; cat TestVerifyError$i.java; for j in /space/jdk1.3.1_03 /space/jdk1.4.0_01 /space/jdk1.4.1_01 /space/jdk1.4.2-beta-b18; do echo $j; $j/bin/javac TestVerifyError$i.java; $j/bin/java -showversion TestVerifyError$i; done; done
---1---
public class TestVerifyError1 {
public static void main(String[] a) {
String x;
try {
x = new String("hello");
} finally {
try {
new String("goodbye");
} catch (RuntimeException e) {
e.printStackTrace();
x = null;
}
}
if (x != null) {
System.out.println(x);
}
}
}
/space/jdk1.3.1_03
java version "1.3.1_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_03-b03)
Java HotSpot(TM) Client VM (build 1.3.1_03-b03, mixed mode)
Exception in thread "main" java.lang.VerifyError: (class: TestVerifyError1, method: main signature: ([Ljava/lang/String;)V) Register 1 contains wrong type
/space/jdk1.4.0_01
java version "1.4.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03)
Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)
Exception in thread "main" java.lang.VerifyError: (class: TestVerifyError1, method: main signature: ([Ljava/lang/String;)V) Register 1 contains wrong type
/space/jdk1.4.1_01
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)
Exception in thread "main" java.lang.VerifyError: (class: TestVerifyError1, method: main signature: ([Ljava/lang/String;)V) Register 1 contains wrong type
/space/jdk1.4.2-beta-b18
java version "1.4.2-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-beta-b18)
Java HotSpot(TM) Client VM (build 1.4.2-beta-b18, mixed mode)
Exception in thread "main" java.lang.VerifyError: (class: TestVerifyError1, method: main signature: ([Ljava/lang/String;)V) Register 1 contains wrong type
---2---
public class TestVerifyError2 {
public static void main(String[] a) {
String x;
try {
x = new String("hello");
} finally {
try {
new String("goodbye");
} catch (RuntimeException e) {
x = null;
}
}
if (x != null) {
System.out.println(x);
}
}
}
/space/jdk1.3.1_03
java version "1.3.1_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_03-b03)
Java HotSpot(TM) Client VM (build 1.3.1_03-b03, mixed mode)
Exception in thread "main" java.lang.VerifyError: (class: TestVerifyError2, method: main signature: ([Ljava/lang/String;)V) Register 1 contains wrong type
/space/jdk1.4.0_01
java version "1.4.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03)
Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)
Exception in thread "main" java.lang.VerifyError: (class: TestVerifyError2, method: main signature: ([Ljava/lang/String;)V) Register 1 contains wrong type
/space/jdk1.4.1_01
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)
Exception in thread "main" java.lang.VerifyError: (class: TestVerifyError2, method: main signature: ([Ljava/lang/String;)V) Register 1 contains wrong type
/space/jdk1.4.2-beta-b18
java version "1.4.2-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-beta-b18)
Java HotSpot(TM) Client VM (build 1.4.2-beta-b18, mixed mode)
hello
###@###.### 2003-03-24
###@###.### 2003-03-24