Name: nt126004 Date: 05/22/2002
FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)
FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version 5.00.2195] with SP2
ADDITIONAL OPERATING SYSTEMS :
All
A DESCRIPTION OF THE PROBLEM :
Under certain circumstances javac generates class_index
values in a constant pool entry for a MethodRef or FieldRef
that refers to the current class instead of the super class
where the field or method was defined.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Write the following two classes:
public class Base {
protected static boolean assertEnabled = true;
protected static void doAssert(boolean cond, String msg) {
if (!assertEnabled) return;
if (cond) return;
throw new RuntimeException("AssertionFailure: " + msg);
}
}
public class Derived extends Base {
static {
Derived.assertEnabled = false;
}
public void foo(int x) {
Derived.doAssert(x > 0, "not >0");
}
}
2. Compile: javac Base.java Derived.java
3. Examine the class file for Derived using a suitable tool
that shows the constant pool.
EXPECTED VERSUS ACTUAL BEHAVIOR :
The constant pool shows a MethodRef for doAssert with a
class_index that refers to Derived, and similarly a
FieldRef for assertEnabled with a class_index that refers
to Derived.
According to the JLS, Section 4.4.2, the class_index is
supposed to refer to the class or interface that contains
the declaration of the field or method. In this case that
should be Base not Derived.
If we change the source code so that the super method and
field are accessed without qualification (ie. doAssert
instead of Derived.doAssert) then the constant pool index
is generated correctly.
Further, if we compile the given code using "-target 1.1"
then again the correct index is generated.
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
public class Base {
protected static boolean assertEnabled = true;
protected static void doAssert(boolean cond, String msg) {
if (!assertEnabled) return;
if (cond) return;
throw new RuntimeException("AssertionFailure: " + msg);
}
}
public class Derived extends Base {
static {
Derived.assertEnabled = false;
}
public void foo(int x) {
Derived.doAssert(x > 0, "not >0");
}
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
compile using -target 1.1
(Review ID: 146875)
======================================================================