• Post Reply Bookmark Topic Watch Topic
  • New Topic

I can access private members of other class in my class  RSS feed

 
Bharat Makwana
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Everyone,

I have following two .java files in the same directory and CLASSPATH is set to "."(Current working directory)
Please Note : I am compiling and running from command prompt

// Use.java


//Provider.java



Now, I compile these two files and if I run Use class,it prints
hi how are you? Bharat
You have Message

Everything is fine upto this. Now I change access modifier at Line #1 and Line #2 from default to private in Provider.java file, I also change variable name's value for "hi how are you? Bharat" to " are you there ?"(at Line #1). I also delete Provider.class file.

After these modifications, I recompile Provider.java file (Please Note:I have just recompile Provider.java file, NOT Use.java) and then if I run , Use class file,it prints

are you there ?
You have Message

I have no idea, how's this possible ?? Can anyone explain me what's going on behind the scene ?

Thank You
[ June 21, 2007: Message edited by: Bharat Makwana ]
 
Bill Cruise
Ranch Hand
Posts: 148
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would start by searching for files containing the text "are you there ?", considering that this is in your output and nowhere in the given source code.

I ran what you provided and got:

java.lang.IllegalAccessError: tried to access method Provider.getMessage()V from class Use
 
Bharat Makwana
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Bill Cruise:
I would start by searching for files containing the text "are you there ?", considering that this is in your output and nowhere in the given source code.


Have followed this step ?(I am compiling and running from command prompt)

Now I change access modifier at Line #1 and Line #2 from default to private in Provider.java file, I also change variable name's value for "hi how are you? Bharat" to " are you there ?"(at Line #1). I also delete Provider.class file.

After these modifications, I recompile Provider.java file (Please Note:I have just recompile Provider.java file, NOT Use.java) and then if I run , Use class file,it prints

are you there ?
You have Message
 
Bharat Makwana
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am using JDK 1.5, Someone in other communities replied that with 1.6 it gives Error,while with 1.5 it does not.

some told on window it works fine under 1.5 and some told with unix you will get error...
 
Leandro Melo
Ranch Hand
Posts: 401
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Bharat.

Access control is performed at compile-time. When you compiled Use.java, bytecodes were corectly generated with a reference to the members of Provider.java you mentioned, because they were public at that time (you can use javap -c to disassemble Use.class and take a look). Afterwards, you recompiled Provider.java and made those members private, but since you did not compile Use.java again, there was no way to detect that those members are no longer public. When you run the application, both Use.class and Provider.class were technically fine. So, you need to recompile Use.java so access control is performed again.
 
Bharat Makwana
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Leandro for reply.

But with jdk 1.6 it gives IllegalAccessError,while with jdk 1.5 it does not(on window platform).

Moreover on unix platform it also give IllegalAccessError with 1.5 and 1.6.
 
Leandro Melo
Ranch Hand
Posts: 401
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Bharat.

I took a look at the JLS (Java Language Specification) and I couldn't find a anything that deals directly with this particular situation. Take a look at this (section 6.6):


The Java programming language provides mechanisms for access control, to prevent the users of a package or class from depending on unnecessary details of the implementation of that package or class. If access is permitted, then the accessed entity is said to be accessible.
Note that accessibility is a static property that can be determined at compile time; it depends only on types and declaration modifiers...


The spec. also gives several examples of cases in which compile time errors occur regarding access violations. But since you recompiled only one file which is part of a larger application, I'm not sure what is defined to be the expected behaviour.
 
Anupam Bhatt
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Doesn't it qualify to be a "flaw". Given that in such kind of scenarios, we are able to access a private method at "runtime", even when the called method has been made private.

should not JVM atleast verify the access specifiers at runtime?

This looks as a hole to me.

Comments?
 
Peter Chase
Ranch Hand
Posts: 1970
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
To be able to do such checks at run-time would require a lot more computation and hugely more storage. Each compiled class would have to contain information about the method signatures of all the classes it used at compile-time, so these could be checked against the ones in the class found at run-time.

To justify this substantial extra burden, you'd have to think up a scenario where it caused bad stuff to happen.

In your case, you've recompiled part of an application in which all the code is yours. Basically, that's a mis-build. It would be nice if Java could detect this, but it's not worth Java doing loads of extra work to do so.

In other cases, one might have an application where much of it is pre-compiled third-party code, and just a bit is one's own code. In that situation, it would be a serious problem if one could defeat the access controls of the third-party code, to give oneself access to methods and data to which the third party didn't intend one to get access. But you can't do that; no amount of recompiling your code will give you access to a private field of the third-party code, for instance.

Note that, for extra protection against code modification, one can use "signed Jars". Google that, if it's an unfamiliar concept.
[ June 25, 2007: Message edited by: Peter Chase ]
 
Anupam Bhatt
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yeah, i agree with you Peter, thanks for the explanation. Sounds logical to me !
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!