-
Bug
-
Resolution: Won't Fix
-
P4
-
None
-
1.0.2, 1.1
-
sparc
-
solaris_2.4
Name: vsC45997 Date: 11/13/96
Let's consider a test checking the following assertion
[The section "13.4.7 Field Declarations" of The Java Language
Specification contains the following]:
"Deleting a field from a class will break compatibility with any
pre-existing binaries that reference this field, and a
NoSuchFieldError will be thrown when such a reference from
a pre-existing binary is linked."
The test below is designed to demonstrate throwing "NoSuchFieldError"
when a deleted field "m" is used.
try {
String s = new Super().m;
....
However when the value of the variable "s" is not used further
in the program, compiler makes optimization and removes "unnecessary" code
namely "m" filed access and assigning to "s". As a result, an absence of field "m"
is not detected in run-time and "NoSuchFieldError" is not thrown.
This optimization seems to be illegal because it changes the program behaviour.
For example, in similar case for arithmetic exception the compiler doesn't
do such optimization:
try {
int s = 1 / new Super().i;
....
And if "i" field is equal to 0 then proper "ArithmeticException" (" / by zero")
is thrown.
The source test consist of two files.
// FILE: binc01501.java
package javasoft.sqe.tests.lang.binc015.binc01501;
import java.io.PrintStream;
class Hyper {
String m = "Hyper";
// int z = 0;
}
class Super extends Hyper {
String m = "Super";
}
public class binc01501 extends Super {
public static void main(String argv[])
{
System.exit(run(argv, System.out) + 95/*STATUS_TEMP*/);
}
public static int run(String argv[],PrintStream out) {
try {
String s = new Super().m;
// out.println(new Super().m);
// int j = 1 / new Super().z;
}
catch (NoSuchFieldError e) {
out.println (e);
return 0;
}
out.println ("failed");
return 2;
}
}
// FILE: binc01501a.java
package javasoft.sqe.tests.lang.binc015.binc01501;
class Super extends Hyper { }
FIRST CASE Java compiler cannot throw NoSuchFieldError
---------- -------------------------------------------
After separate compilation and execution with -verify option we have:
javac -d . binc01501.java
javac -d . binc01501a.java
java -verify javasoft.sqe.tests.lang.binc015.binc01501.binc01501
failed
SECOND CASE Java compiler throws NoSuchFieldError
----------- ------------------------------------
If I uncomment the following line of the file binc01501.java:
// out.println(new Super().m);
then we will have the correct result:
java.lang.NoSuchFieldError: javasoft.sqe.tests.lang.binc015.binc01501.Super: field m not found
THIRD CASE Java compiler acts differently for the ArithmeticException
----------- ----------------------------------------------------------
If I uncomment other lines instead of "out.println(new Super().m);" , namely:
// int z = 0;
// int j = 1 / new Super().z;
then we have:
java.lang.ArithmeticException: / by zero
at javasoft.sqe.tests.lang.binc015.binc01501.binc01501.run(binc01501.java:24)
at javasoft.sqe.tests.lang.binc015.binc01501.binc01501.main(binc01501.java:19)
======================================================================