invokevirtual on package private override in different classloader
Karen Kinnear
Karen.Kinnear at Sun.COM
Tue Apr 14 12:30:38 PDT 2009
Jeff,
Perhaps you can help me duplicate the problem.
First - what does java -version say?
I took the source code appended, and modified the URL setting,
which I believe should just give me your second example, i.e.
CustomSquare instantiated in a different ClassLoader than Printer.
When I run this with Sun's 1.6 or recent 1.7 I get "blue".
What did we do differently?
thanks,
Karen
Jeffrey Sinclair wrote:
> hotspot-dev,
>
> I've been struggling to understand why HotSpot does not throw an
> IllegalAccessError when a call is made to an override of a package
> private method on an instance loaded by a different class loader. I was
> hoping someone could explain to me in technical detail where I'm going
> wrong because it appears to be a bug.
>
> (all source code is pasted at the end of the mail)
>
> I have a class called Square with a package private method named
> getColour() which returns 'red'. I have a subclass of Square called
> CustomSquare which overrides getColour() to return 'blue'. I have
> another class called Printer which simply prints out getColour() for the
> Square passed to it. I then have two test cases:
>
> * Printer.print(Square) is called with a CustomSquare instantiated in
> the same ClassLoader as Printer.
> * Printer.print(Square) is called with a CustomSquare instantiated in
> a different ClassLoader as Printer.
>
> What I find is that I get 'blue' in the first test (as expected) and
> 'red' in the second test (not expected).
>
>>From the Access Control constraints in the Linking section of the JVM
> specification (5.4.4), I as expecting an IllegalAccessError to be thrown
> because it states that a package private method is accessible to a class
> if it is declared by a class in the same runtime package.
>
> My understanding is that Printer is not in the same runtime package as
> CustomSquare which explains why my override does not kick in, but it
> does not explain why an IllegalAccessError is not thrown.
>
> I was wondering if someone could explain the behaviour to me.
>
> Regards,
>
> Jeff
>
> The source code:
>
> public class Main {
> public static void main(String[] args) throws Exception {
> URL[] urls = new URL[]{new URL("path/to/CustomSquare")};
> URLClassLoader loader = new URLClassLoader(urls);
> Class clazz =
> loader.loadClass("uk.co.cooljeff.visibility.CustomSquare");
> Printer printer = new Printer();
> printer.print((Square)clazz.newInstance()); // 'red' gets printed
> }
> }
>
> package uk.co.cooljeff.visibility;
>
> public class Printer {
> public void print(Square square) {
> System.out.println(square.getColour());
> }
> }
>
> package uk.co.cooljeff.visibility;
>
> public class CustomSquare extends Square {
> public CustomSquare() {
> super(5);
> }
>
> @Override
> public String getColour() {
> return "blue";
> }
> }
>
> package uk.co.cooljeff.visibility;
>
> public class Square {
> private float length;
>
> public Square(float length) {
> this.length = length;
> }
>
> public float calculateArea() {
> return length * length;
> }
>
> String getColour() {
> return "red";
> }
> }
>
More information about the hotspot-dev
mailing list