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.