Can access private members !!!!!

Hi All,

Check the programms below

class A

{

publicstaticvoid main(String [] args){

B obj=new B();

System.out.println(obj.msg);

}

}

class B{

String msg="Welcome !!!";

}

compile the above two programs by using javac then run class A by java A

the ouput will be :--

Welcome !!!

Next change the String msg="Welcome !!!";

in class B to

private String msg="Welcome 2008 !!!";

Then compile B.java only .Dont compile A.java again

Then run A by typing java A .The output will be

Welcome 2008 !!!

But msg is declared as private in 2nd case.So how its accessible ?

I think its due to the fact that

accessibility is a static property that can be determined at compile time

Any other reason ?

[1321 byte] By [suvendu_barika] at [2007-11-27 8:27:02]
# 1
> Then compile B.java only .Dont compile A.java again...But you changed the API of B, so naturally you need to recompile A.
warnerjaa at 2007-7-12 20:16:41 > top of Java-index,Java Essentials,Java Programming...
# 2

Ya that change is working even without recompilation as you can see Welcome 2008 !!! is getting printed 2nd time .But my question is the method is private so how this is accessible ?i know if i recompile it it will give me error that you cant access private methods

Message was edited by:

suvendu_barik

suvendu_barika at 2007-7-12 20:16:41 > top of Java-index,Java Essentials,Java Programming...
# 3
Can someone plz answer the correct reason for this question ?Message was edited by: suvendu_barik
suvendu_barika at 2007-7-12 20:16:41 > top of Java-index,Java Essentials,Java Programming...
# 4
See reply #1.
Djaunla at 2007-7-12 20:16:41 > top of Java-index,Java Essentials,Java Programming...
# 5

The above programm will successfully get executed in java-1.4 (tested)and 5 also i think...But in java6 it will throw a exception like

Exception in thread "main" java.lang.IllegalAccessError: tried to access field B

.msg from class A

at A.main(A.java:6)

It something which was unnoticed in earlier version of java but was fixed in java 6

Message was edited by:

suvendu_barik

suvendu_barika at 2007-7-12 20:16:41 > top of Java-index,Java Essentials,Java Programming...
# 6

I just ran your code in 1.4.2, 1.5, and 1.6 and got the same error every time at compilation.

a.java:5: msg has private access in B

System.out.println(obj.msg);

There is likely another class B, possibly in another location on your classpath that you are mistakenly compiling.

There is no way that you could even compile class A when class B's member is private.

Clearly an older version of class B is running.

maple_shafta at 2007-7-12 20:16:41 > top of Java-index,Java Essentials,Java Programming...
# 7

> I just ran your code in 1.4.2, 1.5, and 1.6 and got

> the same error every time at compilation.

> There is likely another class B, possibly in another location on your

> classpath that you are mistakenly compiling.

> There is no way that you could even compile class A when class B's member is private.

> Clearly an older version of class B is running.

I tried it too and got the same results the OP did. He said to compile A and B, and run A. Then, edit B, recompile only B, then run A again (without recompilation).

I'll admit that I'm not entirely sure as to how A was able to print the new message.

KelVarnsona at 2007-7-12 20:16:41 > top of Java-index,Java Essentials,Java Programming...
# 8

It would appear that in 1.4 and 1.5, the VM doesn't check the access level (at least not for static variables--maybe it does for non-statics, or for methods). The compiler obviously does though.

Which begs the question: Are access levels intended to be a runtime thing, or only compile time? Is that a bug pre 1.6, or has the spec changed?

jverda at 2007-7-12 20:16:41 > top of Java-index,Java Essentials,Java Programming...
# 9

hey friends,

after reading http://java.sun.com/docs/books/jls/second_edition/html/binaryComp.doc.html#44909

which says...

"Given a legal expression denoting a field access in a class C, referencing a field named f declared in a (possibly distinct) class or interface D, we define the qualifying type of the field reference as follows:

* If the expression is of the form Primary.f then the compile-time type of Primary is the qualifying type of the reference."

it seems that when we are compiling the sources for the first time, a reference to B.msg is registered in A.class with protected type, thats why we are able to access B.msg from A.

If i am not wrong... one point to note here is that by default B.msg should have private access but because of the above reason it is not.

Now, when we are compiling B with modified access scope, the reference in A is not updated that why it is still accessible from A.

This is just a guess work... and we need explanation from a Java expert...

regards

i_virus

i_virusa at 2007-7-12 20:16:41 > top of Java-index,Java Essentials,Java Programming...
# 10

I think it was supposed to be a loadtime test (sort of runtime).

If this is true then it is a gaping security hole. Get hold of the binaries (and decompile them) or the source of the code you are going to plug into. modify the private members to be public. Compile your attack code against this code base and then submit your plugin to run against the real codebase. You could use it to potentially screw over security mangers in applets.

However I can see that a load time test would be pretty expensive to do. You would have to verify that all loaded classes do not reference a private variable of a class being loaded and that all classes being loaded do not try to access the privates of already loaded classes. Or you would have to test for privalage on all accesses to all members (kind of a large overhead)

It might behave differently if you have a security manager (by default java does not).

I believe that in 1.6 the class verification system was made faster and possibly more robust (metadata is added to classfiles when they are compiled to assist in the verification (which is also open to abuse))

matfud

Message was edited by:

matfud

matfuda at 2007-7-12 20:16:41 > top of Java-index,Java Essentials,Java Programming...
# 11
One thing I do know is that, at least up to jdk 1.4, you could access private members via reflection if there was no security manager. However I thought that was because the security manager checked the reflection methods rather then checking all access to all members.matfud
matfuda at 2007-7-12 20:16:41 > top of Java-index,Java Essentials,Java Programming...
# 12
I made a mistake in my last post...I had recompiled the A class so it did give me a compile error.I tried again and I got the same results as the OP.
maple_shafta at 2007-7-12 20:16:41 > top of Java-index,Java Essentials,Java Programming...
# 13

> The above programm will successfully get executed in

> java-1.4 (tested)and 5 also i think...But in java6 it

> will throw a exception like

>

> Exception in thread "main"

> java.lang.IllegalAccessError: tried to access field

> B

> .msg from class A

> at A.main(A.java:6)

> ething which was unnoticed in earlier version of java

> but was fixed in java 6

>

I think in jdk 1.4 and 5 the access modifier checking is compile time only. Since as you told it is working on java 6 (I have not tested) so they must changed this to check in runtime.. I have posted the same problem earlier at http://forum.java.sun.com/thread.jspa?threadID=782593&messageID=4450029#4450029

ant got the above responses from some other members..

diptaPBa at 2007-7-12 20:16:41 > top of Java-index,Java Essentials,Java Programming...