invokevirtual on package private override in different classloader
Karen Kinnear
Karen.Kinnear at Sun.COM
Thu Apr 16 14:42:32 PDT 2009
Jeff,
Thank you for sending me this information. I have a theory, but I
would be much more comfortable running the test first. I have
experimented
with this, but I'd feel much more comfortable duplicating your results.
I do appreciate you offering to package this up using plain old javac/
and
a run script - I don't have Eclipse installed and much as I've heard it
is a great product, I don't have the cycles to do that in the near
future.
thanks so much,
Karen
On Apr 14, 2009, at 5:33 PM, Jeffrey Sinclair wrote:
> Karen,
>
> Thanks for getting back to me.
>
> I was using 1.6.0_10 and have now tried 1.6.0_13 and get the same
> result. Specifically I've tried the following versions:
>
> java version "1.6.0_10"
> Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
> Java HotSpot(TM) 64-Bit Server VM (build 11.0-b15, mixed mode)
>
> java version "1.6.0_13"
> Java(TM) SE Runtime Environment (build 1.6.0_13-b03)
> Java HotSpot(TM) 64-Bit Server VM (build 11.3-b02, mixed mode)
>
> I've attached my source as Eclipse projects. The URL in the main
> method
> points to the class files generated by the project with the
> CustomSquare. I've also added some debug info relating to which class
> loader is being used to load the Square, Printer and Custom Square
> respectively:
>
> Printer loaded by classloader: sun.misc.Launcher
> $AppClassLoader at 553f5d07
> Square loaded by classloader: java.net.URLClassLoader at 3ae48e1b
> CustomSquare loaded by classloader: java.net.URLClassLoader at 3ae48e1b
> Red
>
> I still get Red. The key point is that the CustomSquare is not visible
> at all to the Printer code. If I stick the CustomSquare in the same
> project as Printer it will then be loaded by the AppClassLoader and I
> get blue. However when it is in a completely separate project and
> loaded
> via the URLClassLoader (and Printer loaded via the AppClassLoader) I
> always get Red. If I then change getColour() to be public in both
> Square
> and CustomSquare I get blue.
>
> This is completely baffling me. I may be doing something really silly
> but I can't see it :)
>
> Let me know if you can't replicate the issue with the attached Eclipse
> project and I'll try to package it up using plain old javac and a run
> script.
>
> Even if you do get blue with the different ClassLoaders for Printer
> and
> CustomSquare, I would probably argue that this is incorrect but I have
> to admit that this argument could be because I've misunderstood the
> meaning of 'runtime package' in terms of package private accessibility
> in the JVM spec.
>
> Jeff
>
> On Tue, 2009-04-14 at 15:30 -0400, Karen Kinnear wrote:
>> 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";
>>> }
>>> }
>>>
>>
> <DefaultVisibilityOverride.zip>
More information about the hotspot-dev
mailing list