-
Bug
-
Resolution: Fixed
-
P4
-
1.0, 1.1, 1.2.0
-
1.2fcs
-
generic, x86, sparc
-
solaris_2.5.1, solaris_2.6, windows_nt
-
Not verified
We currently have a known problem with programs which legally access
public/protected members belonging to inaccessible classes.
Compile the following program:
::::::::::::::
one/DefineFooBar.java
::::::::::::::
package one;
class DefineFooBar {
public int foo = 3;
protected int bar = 4;
}
::::::::::::::
one/GrantAccess.java
::::::::::::::
package one;
public class GrantAccess extends DefineFooBar {
}
::::::::::::::
two/UseFooBar.java
::::::::::::::
package two;
public class UseFooBar extends one.GrantAccess {
public void use() {
System.out.println(foo + " " + bar);
}
public static void main(String[] args) {
new UseFooBar().use();
}
}
::::::::::::::
When it is run, we get an IllegalAccessError:
::::::::::::::
$ java two.UseFooBar
Exception in thread "main" java.lang.IllegalAccessError: try to access class one/DefineFooBar from class two/UseFooBar
at two.UseFooBar.use(Compiled Code)
at two.UseFooBar.main(Compiled Code)
::::::::::::::
This is a caused by a problem in the spec. The JLS section 13.1
requires that the access to foo be compiled as:
getfield Field one/DefineFooBar.foo:"I";
The exact language is "A reference to a field of another class or
interface must be resolved at compile time to a symbolic reference to
the class or interface in which the field is declared."
However, when the VM attempts to verify this access, it does not take
into account that one.DefineFooBar is a superclass of two.UseFooBar --
it just knows that one.DefineFooBar is not accessible from UseFooBar
and throws an exception. This behavior is not likely to change.
So, there must be some rewording of 13.1 which allows the above code
to run. Changing the access to one of
getfield Field one/GrantAccess.foo:"I";
getfield Field two/UseFooBar.foo:"I";
will allow the access to succeed on post-1.1 VMs.
As soon as the spec people decide on an appropriate course, we will
introduce the appropriate fix in the compiler.
The same bug exists for method calls as well.
(Note that the above program is legal: without getting into details,
section 8.2 defines the members of a type to be all members inherited
from its direct superclass. This means GrantAccess inherits foo from
DefineFooBar, and UseFooBar inherits foo from GrantAccess. There is
no special language restricting access based on the type in which the
member was initially declared.)
public/protected members belonging to inaccessible classes.
Compile the following program:
::::::::::::::
one/DefineFooBar.java
::::::::::::::
package one;
class DefineFooBar {
public int foo = 3;
protected int bar = 4;
}
::::::::::::::
one/GrantAccess.java
::::::::::::::
package one;
public class GrantAccess extends DefineFooBar {
}
::::::::::::::
two/UseFooBar.java
::::::::::::::
package two;
public class UseFooBar extends one.GrantAccess {
public void use() {
System.out.println(foo + " " + bar);
}
public static void main(String[] args) {
new UseFooBar().use();
}
}
::::::::::::::
When it is run, we get an IllegalAccessError:
::::::::::::::
$ java two.UseFooBar
Exception in thread "main" java.lang.IllegalAccessError: try to access class one/DefineFooBar from class two/UseFooBar
at two.UseFooBar.use(Compiled Code)
at two.UseFooBar.main(Compiled Code)
::::::::::::::
This is a caused by a problem in the spec. The JLS section 13.1
requires that the access to foo be compiled as:
getfield Field one/DefineFooBar.foo:"I";
The exact language is "A reference to a field of another class or
interface must be resolved at compile time to a symbolic reference to
the class or interface in which the field is declared."
However, when the VM attempts to verify this access, it does not take
into account that one.DefineFooBar is a superclass of two.UseFooBar --
it just knows that one.DefineFooBar is not accessible from UseFooBar
and throws an exception. This behavior is not likely to change.
So, there must be some rewording of 13.1 which allows the above code
to run. Changing the access to one of
getfield Field one/GrantAccess.foo:"I";
getfield Field two/UseFooBar.foo:"I";
will allow the access to succeed on post-1.1 VMs.
As soon as the spec people decide on an appropriate course, we will
introduce the appropriate fix in the compiler.
The same bug exists for method calls as well.
(Note that the above program is legal: without getting into details,
section 8.2 defines the members of a type to be all members inherited
from its direct superclass. This means GrantAccess inherits foo from
DefineFooBar, and UseFooBar inherits foo from GrantAccess. There is
no special language restricting access based on the type in which the
member was initially declared.)
- duplicates
-
JDK-4152885 Inherited method from package private class throws IllegalAccessError
- Closed