• Post Reply Bookmark Topic Watch Topic
  • New Topic

Java Reflection Problem  RSS feed

 
Ranch Hand
Posts: 231
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Friends,

I am learning Java Reflection. I have created a class which has one member as a PRIVATE member. Using reflection i am trying to print out all the members, their types and values of that class. So i create an object of that class and use Reflection API to look into the object of that class. The program throws an exception if a private member is encountered by the Reflection API while printing its value. Is their any way by which i can read the values of the private members also ?

 
Sheriff
Posts: 21135
87
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Call setAccessible(true) on the member. The current SecurityManager can still block access though.
 
omkar patkar
Ranch Hand
Posts: 231
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Rob,

Thank you for your help!!! It worked. But i am little skeptical, if the program will work on all machines. As the security settings of JVM for different machines
can be different. Can you please guide me with overriding the security settings of JVM for my custom program? Is it possible ?

 
Ranch Hand
Posts: 128
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It depends on the VM settings, whether you can use reflection on private fields or not. See the Javadoc and the permission's guide for the SecurityManager. The reflection accessibility is on by default (there is no SecurityManager) but it can be changed eg. on an application server or another production environment.
 
omkar patkar
Ranch Hand
Posts: 231
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

After the setAccessible worked @ my home, i thought of writing a similar program in my office machine. Here is the code: -

Event.java


and the Test1.java contains the void main function that will use Reflection to look into the fields of an Event object, which is as follows: -

Test1.java



The output i get is : -
No of fields are 2
Exception in thread "main" java.lang.IllegalAccessException: Class Test1 can not access a member of class Event with modifiers "pr
ivate"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:57)
at java.lang.reflect.Field.doSecurityCheck(Field.java:811)
at java.lang.reflect.Field.getFieldAccessor(Field.java:758)
at java.lang.reflect.Field.get(Field.java:228)
at Test1.main(Test1.java:40)


... i googled a bit, and realised i can set a custom security policy to overide the default security settings. However, the customized security policy also did not work!!!

so i wrote a security policy file using the "policytool". The policy files looks like this : -

ReflectionTest.policy


my code .. i.e., the Event.java, Test1.java and the corresponding class files are in the directory same as the policy file .. i.e.,

C:/Dynamo/SourceEnvironment/TestProject/


Since, i had created a custom security policy file, i executed the Test1.java program at command line as : -

C:\Dynamo\SourceEnvironment\TestProject>java -Djava.security.manager -Djava.security.policy=ReflectionTest.policy Test1


... But still i am getting the same exception.
No of fields are 2
Exception in thread "main" java.lang.IllegalAccessException: Class Test1 can not access a member of class Event with modifiers "pr
ivate"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:57)
at java.lang.reflect.Field.doSecurityCheck(Field.java:811)
at java.lang.reflect.Field.getFieldAccessor(Field.java:758)
at java.lang.reflect.Field.get(Field.java:228)
at Test1.main(Test1.java:40)



Can someone please help me out ??

 
Rob Spoor
Sheriff
Posts: 21135
87
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Call setAccessible(true) before you retrieve the value.
 
omkar patkar
Ranch Hand
Posts: 231
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ohh Nooo !!! .... Rob you are right. Thanks man!!!

It worked!!!

I shifted the setAccesible() call ....before getting the value.

... one last thing. The kind of setting that i do in my policy file, can i do it in my code? ... because my code will be used as utitlity class. So i cannot set the policy file and security manager parameter as i did in the command line version. That is i cannot use : - -Djava.security.manager AND -Djava.security.policy=ReflectionTest.policy.

So how do i override the security settings for reflection in code as i did in the policy file?

Many thanks again!!
 
Rancher
Posts: 42972
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The kind of setting that i do in my policy file, can i do it in my code? ... because my code will be used as utitlity class. So i cannot set the policy file and security manager parameter as i did in the command line version.


In general, you can do "System.setSecurityManager(new MySecurityManager())", and then have the MySecurityManager class override the checkPermission methods to allow whatever specific permissions it needs to. But that won't work in an environment where there's a security manager in place already, which is often the case in an app server or a servlet container.
 
Adam Michalik
Ranch Hand
Posts: 128
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try System.setProperty("java.security.policy", "ReflectionTest.policy"), but I think that changing it at the run time will have no effect. To change the security manager I think you'd need System.setSecurityManager(). However both calls require permissions from the current security manager. So there is no 100 % sure version that the reflection tricks on the private fields will ever work. That's what the security is for, in the end ;) In my opinion if you're writing an utility class it would be better not to touch the security manager and the security policies. It's up to the user to maintain the security permissions. If the user does not give your class such permissions, it's his/her responsibility, not yours.
 
omkar patkar
Ranch Hand
Posts: 231
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ohh No !!!
That means even if i am able to create the utility class, then i won't be able to use it in my web application!!!

... Actually, i want to write a utility that will convert java objects by looking into it, ---- into a file. Like serialization.
But, the format in which the state of the objects will be saved in the file is specific. The file can be XML, JSON, etc.,

There must be some way ??? .... else no other similar frameworks will ever work, especially in web containers.

Isn't there any way ???
 
Adam Michalik
Ranch Hand
Posts: 128
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, I would say that it is not your problem but the user's. Most of the frameworks that work with Object-To-Something-Mappings use reflection, so I would not be so afraid that the reflection permissions are revoked. And if they are, the user or the administrator of the server that does not permit reflection has got to know and agree that he or she makes it impossible for such object mapping frameworks to work. I'd say that it's nearly impossible that someone would revoke such permissions in an application that does object mappings. And even if the permissions are generally revoked, there can be an exception made for your library - see the guide on security policy files. It is however the responsibility of the user.
 
omkar patkar
Ranch Hand
Posts: 231
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Adam,

Sorry, i did not get your point. May be you can help with an example?
In my case, on the server, if i run the following command (Solaris is the OS),

"ps -ef | grep java"


then i get to see the java processes running and the one used by server is with the security policy.

It looks something like this : -

/opt/oracle/OraHome_1/jdk/bin/java -server -Djava.security.policy=/opt/oracle/O....


This will mean, that the security manager provided by oracle (OC4J) will be used by the jvm. right ?
Now my utility class or jar is present in a web application hosted IN THIS server.
That means, my web app will run IN THIS
JVM which is configured with THESE security settings.

Since i have no control over the security manager of OC4J, my code will
never work! ... This is my understanding so far ... am i going in right direction???


In such cases, if i write a custom security policy file which will permit access only for REFLECTION
and that too only to my utility code or jar file, and ask the server administrator to configure the jvm
to use my custom security policy file instead of OC4J security policy file, then will it work ?
Will the other security permissions like, FILE, NETWORK etc., be retained? I don't wish to override those!!!

Please let me know if i am thinking in right direction ?
 
Adam Michalik
Ranch Hand
Posts: 128
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, the best solution in that case would be to contact the administrator of the server and require an exception for your classes to allow reflection. It would be best that you write a file snippet for that, giving permission to your library, and the administrator merges your policy with the existing one. Check the guide on writing policy files mentioned earlier, there are several ways to express that a permission should be granted (Jar-file based, signature based etc.). Please let know when you finally solve the problem, it is an interesting issue
 
omkar patkar
Ranch Hand
Posts: 231
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Adam,

Thank you so much !!!
So, i will have to inform the admin to add or append my policy setting into the policy file used by
the current JVM. This way it should surely work !!!

Sure, its very interesting! i will let you know.
But it will take some time, as i was by now doing RnD to know possible problems i can face
before proceeding with the utility classes. Moreover, i need to make them generic, so that, it can
be used in other projects of the company. So give me some time... i will surely let you know
how it worked.

Many thanks again Adam and all !!!

... i will be back !!! (for more doubts !!!)
 
Adam Michalik
Ranch Hand
Posts: 128
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My pleasure Good luck!
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!