Re: [Clirr-devel] Java doesn't appear to do runtime checks for class/method access rights
Status: Alpha
Brought to you by:
lkuehne
From: <lak...@t-...> - 2004-07-05 18:03:58
|
Simon Kitching wrote: >Hi Lars, > >Could you please check that I haven't gone completely mad? > >Attached is an archive which contains some java code that appears to >demonstrate that the Java JVM/runtime does not check for class or method >access rights. > >Try: >* cd v1; javac Foo.java >* cd v2; javac Foo.java >* cd .. >* cp v1/Foo.class pkg >* javac Main.java >* java Main >--> so far, all as expected. > >But now: >* cp v2/Foo.class pkg >* java Main >--> the main class successfully invokes a private method on > the package-scope Foo class! > >The java lang spec document seems clear that this *should* throw an >IllegalAccessError, but it doesn't. I would like someone to confirm that >I am not having hallucinations here before I add a note about this to >the message description document. > >I've tried this with: >* sun java 1.3 on AIX >* sun java 1.4 on linux >* sun java 1.5 on linux >* IBM java 1.4 on AIX >* IBM java 1.4 on linux >and they all give the same result. > >Regards, > >Simon > > I can confirm your results: access> java Main public method f1 of package scope class Foo called! private method f2 of package scope class Foo called! Wow!! This is scary, but on the other hand it's quite logical. Try to disassemble the code of Main: access> javap -private -c Main Compiled from "Main.java" public class Main extends java.lang.Object{ public Main(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: new #2; //class pkg/Foo 3: dup 4: invokespecial #3; //Method pkg/Foo."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #4; //Method pkg/Foo.f1:()V 12: aload_1 13: invokevirtual #5; //Method pkg/Foo.f2:()V 16: return } It seems the bytecode for both method calls is the same. The Main class simply seems to have no record whether the called methods are private or public, so the VM can't check anything... ? I couldn't find the IllegalAccessError requirement you mentioned, but in $13.4.6 the JLS says: "Changing the declared access of a member or constructor to permit less access may break compatibility with pre-existing binaries, causing a linkage error to be thrown when these binaries are resolved. Less access is permitted if the access modifier is changed from default access to |private| access; from |protected| access to default or |private| access; or from |public| access to |protected|, default, or |private| access" Not quite sure what to make of this, to me the spec is quite confusing - aren't those two sentences contradicting each other? Still surprised, Lars |