I am trying to understand the drawbacks as mentioned in Java docs
Security Restrictions
Reflection requires a runtime permission which may not be present when
running under a security manager.
What are the runtime permissions that reflection needs? What is security manager in this context? Is this drawback specific to Applets only?
Exposure of Internals
Since reflection allows code to perform operations that would be
illegal in non-reflective code, such as accessing private fields and
methods, the use of reflection can result in unexpected side-effects,
which may render code dysfunctional and may destroy portability.
Reflective code breaks abstractions and therefore may change behavior
with upgrades of the platform.
How reflection can break abstraction? and how does it affect with upgrades of the platform.
Please help me in clarifying these. Thanks a lot.
First you should always ask to yourself why reflection in your code. Aren't you able to do the operations without reflection. If YES then only you should use reflection. Reflection uses meta information about class,variables and methods this increase overhead, performance issue and security threat.
To understand the drawback of reflection in detail visit http://modernpathshala.com/Forum/Thread/Interview/310/what-are-the-drawbacks-of-reflection
Security "sandboxes" aren't limited to applets. Many other environments which permit less-than-completely-trusted "plug-in" code -- webservers, IDEs, and so on -- limit what the plug-ins can do to protect themselves from errors in the plug-in (not to mention deliberately malicious code).
A framework class called dependency container was used to analyzes the dependencies of a class. With this analysis, it was able to create an instance of the class and inject the objects into the defined dependencies via Java Reflections. This eliminated the hard dependencies. That way the class could be tested in isolation, ex. by using mock objects. This was Dagger 1.
Main disadvantages of this process were two folds. First, the Reflection is slowing itself and second, it used to perform dependency resolution at runtime, leading to unexpected crashes.
Related
This follows on from this question, which is about Groovy (a superset/modernisation of Java), where there is, seemingly, essentially no information-hiding and no encapsulation whatsoever.
But in Java too of course there is reflection, meaning that private, protected and package-private are essentially pointless, or worse: create a false sense of security.
In Java, is there any way to enforce visibility, of some kind, not necessarily in the sense of specifically enforcing the above visibility modifiers, and package-private, using a SecurityManager? I've only just started looking into the latter and I can't see any very obvious way of accomplishing something like that. But it would seem that some developers must ship code where some classes and methods do not have completely public visibility... so how is it done?
PS in the Lucene package, with which I'm a bit familiar, I notice that quite a lot of classes turn out to be final (which has sometimes caused me some head-scratching...) but I'm pretty sure, although not certain, that reflection can be used to squash that modifier
Can I write my classes to be setAccessible-proof regardless of SecurityManager configuration? ... Or am I at the mercy of whoever manages the configuration?
You can't and you most certainly are.
Anybody who has access to your code can configure their JVM and SecurityManager as they please. (more details below)
Is setAcessible legitimate? Why does it exist?
The Java core classes use it as an easy way to access stuff that has to remain private for security reasons. As an example, the Java Serialization framework uses it to invoke private object constructors when deserializing objects. Someone mentioned System.setErr, and it would be a good example, but curiously the System class methods setOut/setErr/setIn all use native code for setting the value of the final field.
Another obvious legitimate use are the frameworks (persistence, web frameworks, injection) that need to peek into the insides of objects.
And finally...
Java access modifiers are not intended to be a security mechanism.
So what can I actually do?
You should take a deeper look into Security Providers section of the Java SE Security documentation:
Applications do not need to implement security themselves. Rather,
they can request security services from the Java platform. Security
services are implemented in providers
The access control architecture in the Java platform protects access to sensitive resources (for example, local files) or sensitive application code (for example, methods in a class). All access control decisions are mediated by a security manager, represented by the java.lang.SecurityManager class. A SecurityManager must be installed into the Java runtime in order to activate the access control checks.
Java applets and Java™ Web Start applications are automatically run with a SecurityManager installed. However, local applications executed via the java command are by default not run with a SecurityManager installed. In order to run local applications with a SecurityManager, either the application itself must programmatically set one via the setSecurityManager method (in the java.lang.System class), or java must be invoked with a -Djava.security.manager argument on the command line.
I recommend you read further about this on the official security documentation
https://docs.oracle.com/javase/7/docs/technotes/guides/security/overview/jsoverview.html
I'm developing a library that needs to access layout items of the app implementing it. The only way I know how to do it is with reflection. In other words, if I create a constructor to my Library API like this:
public MyLibraryAPI(String packageName) {
Class appR = Class.forName(String.format("%s.R", packageName));
...
}
And the developer would instantiate the library with his package name as the parameter in the constructor.
What I ultimately need is to let my inner classes know the Android Views used in the developers layout (.xml files) - both the id and the type. Is there a way to achieve this without reflection and escape the performance overhead? I'm certain it cannot be done, but asking in case there's an expert that sees what I fail to notice.
EDIT: Additionally, proguard, by default, obfuscates the code for protection but, as a consequence, fails to provide JVM with means to achieve reflection at runtime, so if I use reflection I would have to ask the developer to turn off proguard obfuscation for his or her R class which is a bummer.
Reflection on Android is extremely costly. Some well-meaning and popular libraries like Roboguice have fallen over partly because of the performance cost of reflection.
I suspect some kind of code generation is the correct solution here. Dagger 2, Butter Knife and the Data Binding Library are successful examples of Android libraries that employ code generation. Since the data binding library performs inspections on the XML, it must be available to code generation libraries at that stage in the build and you may be able to base your implementation on that: here's a link to the source jars at Maven Central.
Apart from that, yes it seems there will be some compromise between ease of use and difficulty-to-implement. If you force your consumers to annotate their classes with your annotations, it becomes harder to use but probably much easier for you to implement. If you restrict yourself to inspecting XML and the generated R file and generating code from just that then I think your job will be a lot more difficult. On the other hand, using annotations has become rather commonplace and it may not be such an issue with your users.
Good luck!
This question already has answers here:
If reflection in Java slows down execution by orders, why do so many frameworks use it ?
(2 answers)
Closed 7 years ago.
Using reflection in Java is very expensive because it affects performance very badly right.But I wonder that , reflection is widely used in container configurations (web.xml),frame works like Structs,REST.. , and ORM like hibernate etc.
How it can be justified?Is it because reflection used only once when container is up or some other reason behind it?
There is no other way for them to do what they do (a good example of this might be Spring framework - it doesn't force you to use any interface when using dependency injection, and since it has no interface to use and doesn't know your classes at compile time, the only way is to inspect them via reflection)
The reflection-heavy parts are not (should not) be executed too often
Reflection isn't that very expensive if done right (e.g. if you only lookup the method you want to call once and then cache the java.lang.reflect.Method object found and use it in further invocations)
First, I wouldn't say that using reflection has such a detrimental effect on code performance. Of course, there is an overhead, but there are optimisation techniques in place, that make sure that the performance impact is kept to a minimum. As far as the trade - off between performance and usability is concerned, the specific requirements of the product being developer should be taken into account. For example, would I use a heavy reflection - based framework on mobile - I think not. Does it makes sense on the backend - I would say yes.
Second, having annotation based configuration doesn't always mean that there is reflection used at application runtime. There are frameworks that make use of the AnnotationProcessor framework and generate java code during compilation, which is later used as "normal code". Also, a lot of frameworks use annotation configuration in conjunction with byte - code generation at runtime, so basically, reflection is kept at a minimum.
In software development we are all using the libraries by software providers. Consider in class A there are four functions viz., x,y,z. I just want my development team to avoid using the function x. So instead of telling them not to use, I found an idea. Inherit the class and override all the functions and for the function x an unsupportedmethod exception is thrown and for the rest I'm calling the super methods. There also I found a problem, developers can use the base class A directly, how to avoid the class A being used directly. I found a similar functionality in OSGi, the lib bundles can be brought in and then not exported and so on. Is there are any way to achieve this is java?
I suppose code reviews exist for these reasons. Consider situation where you can not edit the source of a third party, what would you do ? Like Siddharth says, sub class it and throw a meaningful exception and document it with a clear reasons. If someone is using base class even after that, mostly it may not out of ignorance,but it may out of curiosity. That kind of thing can be appreciated personally and for learning, but for the project sake developer has to follow the guidelines.
I think simply telling your developers what to do is preferred over a complex software solution. Sometimes the simple thing is better.
But, if you insist on going down this path, you can enforce your architecture standards using aspects if you're a Spring user. Weave the offending methods with an aspect that throws an exception if they're called.
You can edit library class file in hex editor and modify its access modifier from public to package private. Also you can rename it and then use inheritance to wrap this class. Here you can find class file specification. Once I've tried this technique to substitute jdbc driver class with wraper class that provide some additional logging and other useful tricks.
There is a variety of tools that check source code for adherence to certain rules, such as formatting, dead code, naming conventions for variables etc. Popular ones for Java include the Maven Enforcer plugin, checkstyle and PMD.
These might allow you to write a rule that forbids certain method calls. Then you could check automatically at compile time. As far as I can tell, unfortunately none of the tools above support "illegal method calls" out-of-the-box; however, at least for PMD writing new checks is fairly simple.
I'm developing a system that allows developers to upload custom groovy scripts and freemarker templates.
I can provide a certain level of security at a very high level with the default Java security infrastructure - i.e. prevent code from accessing the filesystem or network, however I have a need to restrict access to specific methods.
My plan was to modify the Groovy and Freemarker runtimes to read Annotations that would either whitelist or blacklist certain methods, however this would force me to maintain a forked version of their code, which is not desirable.
All I essentially need to be able to do is prevent the execution of specific methods when called from Groovy or Freemarker. I've considered a hack that would look at the call stack, but this would be a massive speed hit (and it quite messy).
Does anyone have any other ideas for implementing this?
You can do it by subclassing the GroovyClassLoader and enforcing your constraints within an AST Visitor. THis post explains how to do it: http://hamletdarcy.blogspot.com/2009/01/groovy-compile-time-meta-magic.html
Also, the code referenced there is in the samples folder of Groovy 1.6 installer.
You should have a look at the project groovy-sandbox from kohsuke. Have also a look to his blog post here on this topic and what is solution is addressing: sandboxing, but performance drawback.
OSGi is great for this. You can partition your code into bundles and set exactly what each bundle exposes, and to what other bundles. Would that work for you?
You might also consider the java-sandbox (http://blog.datenwerke.net/p/the-java-sandbox.html) a recently developed library that allows to securely execute untrusted code from within java.
Also see: http://blog.datenwerke.net/2013/06/sandboxing-groovy-with-java-sandbox.html