On Fri, Oct 8, 2010 at 3:56 PM, Alessio Stalla <[email protected]> wrote:
> On Fri, Oct 8, 2010 at 3:47 PM, Jochen Theodorou <[email protected]> wrote:
>> Alessio Stalla wrote:
>> [...]
>>>
>>> I'm not an expert about that. Generally linking is done very lazily by
>>> the JVM, so it might not occur if you CHECKCAST a null pointer. When
>>> instead you have a live object, a CHECKCAST might count as an access
>>> to the referenced class and trigger the illegal access error. I'm
>>> guessing, mind you; let's see if someone who knows the JVM better has
>>> something different to say.
>>
>> but why is the access illegal? The class might be package private, but the
>> calling class is in the same package and thus allowed to access that class.
>> If not the Java version of it would not even compile.
>
> As I said at runtime "same package" means "same package name" AND
> "same classloader" or at least this is my interpretation of the jvm
> spec, so if you have two different classloaders loading your two
> classes like you said, they're not considered to be in the same
> package. In the Java version evidently there's only one classloader
> involved.

In fact, I think I managed to reproduce it. I have this structure:

<default package>/
  Main2.java
  pkg/
    A.java
    B.java

Main.java has the following main method:

------------------------
public static void main(String[] args) {
                try {
                        ClassLoader a = new URLClassLoader(new URL[] { new
URL("file:///home/alessio/prova1/") });
                        System.out.println("a = " + a);
                        a.loadClass("pkg.A");
                        ClassLoader b = new URLClassLoader(new URL[] { new
URL("file:///home/alessio/prova2/") }, a);
                        System.out.println("b = " + b);
                        b.loadClass("pkg.B").getMethod("foo").invoke(null);
                } catch(Exception e) {
                        e.printStackTrace();
                }
        }
--------------------------

A.java is

------------------
package pkg;

class A {
        static { System.out.println("A loaded by " + A.class.getClassLoader()); 
}
        public String aaa() { return "foo"; }
}
----------------

B.java is

------------------
package pkg;

public class B {
        static { System.out.println("B loaded by " + B.class.getClassLoader()); 
}
        public static void foo() {
                Object o = new A();
                System.out.println(((A) o).aaa());
        }
}
------------------

I compile them, then move A.class to ~/prova1/pkg/ and B.class in
~/prova2/pkg/ and then I issue the command:

ales...@astalla-laptop:~$ java -cp workspace/prova/bin Main2
Main2 loaded by sun.misc.launcher$appclassloa...@13f5d07
a = java.net.urlclassloa...@1eed786
b = java.net.urlclassloa...@12dacd1
B loaded by java.net.urlclassloa...@12dacd1
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at Main2.main(Main2.java:13)
Caused by: java.lang.IllegalAccessError: tried to access class pkg.A
from class pkg.B
        at pkg.B.foo(B.java:10)
        ... 5 more

Granted, this is not caused by a CHECKCAST, but the principle is the same.

Bye,
Alessio

-- 
You received this message because you are subscribed to the Google Groups "JVM 
Languages" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/jvm-languages?hl=en.

Reply via email to