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