On 13 July 2016 at 22:47, <[email protected]> wrote: > To put what Alex wrote in a somewhat different way, I'd say that the > tension here is between explicit configuration (as one finds today in, > e.g., the Maven world) and implicit configuration (IoC). Both approaches > are important. The former is typical of standalone Java SE applications > while the latter is typical of Java EE applications, though the two > approaches are often intermixed.
I would caution against simplistic use cases for reflection and setAccessible. Both are widely used, and I would argue are one of the cornerstones of the success of Java. ie. Java provides a nice safe world for most developers, but provides the ability to step down and access the internals if necessary. Looking through the code currently in my IDE I see reflection and setAccessible used for: - access Unsafe, for which alternatives are being provided (lots) - access beans for command line setting (JCommander) - access bean properties (Joda-Beans) - access beans for XML/JSON/binary serialization (Joda-Beans) - access Types.newParameterizedType() in Guava (Joda-Convert) - access Thread.inheritableThreadLocals (Guava) - set final fields during deserialization (Guava) - deliver messages to annotated subscriber methods (Guava) - set private fields during configuration (BoneCP) - find enum-like constants declared in a class (Strata-Collect) - access beans (Sleepycat) - set field to workaround bug in HttpURLConnection (Jersey) - access and invoke annotated fields/methods (Jersey) - access ClassLoader.defineClass to create class from bytecode (Jersey) - access JAXB element name by creating an instance to call API (Jersey) - access methods for expression language walking (JUEL) - invoke task started/finished API in Ant (Groovy) - creating bytecode and querying generated proxies (Javassist) - create bean instance and bind to fields/methods (EHCache) - query all fields to determine object size (EHCache) - expression language (EHCache) - obtain an instance for testing (Terracotta) - access field/method for parsing (Antlr) - produce a toString() based on fields (ActiveMQ) - access beans (Commons-BeanUtils) - access fields/methods (Commons-Lang) - delayed deserialization of large matrix, setting field (Commons-Math) - merge two objects, setting non-public field (Apache Shiro) - produce a toString() based on fields (KahaDB) - create an instance of a failure in JUnit (AssertJ) - inject from JNDI into a bean field/setter (Jetty) - invoke a lifecycle method (Jetty) - access ClassLoader.defineClass to create class from bytecode (Hawt-Dispatch) - produce a toString() based on fields (Hawt-Dispatch) - access beans for ORM query/update (HIbernate) - access beans for ORM code generation (HIbernate) - access beans for JSON serialization (Jolokia) - spy on fields/methods (Mockito) - access Java deserialization internals (Objenesis) - access SqlMapConfigParser.state in iBATIS (Spring) - expression language (StringTemplate) - create and run tests (TestNG) (this doesn't list every use, just some key/obvious ones) Looking through this list (obtained by manually examining uses of setAccessible) there are some repeating patterns, but other use cases are unique. The common ones are: - beans and properties (includes config, serialization, ORM and expression language) - reflection-based toString() - related to beans/properties - accessing something in another project that should have been public - accessing something in another project to workaround a bug - access Unsafe I did this to ensure that me expectation was correct - that reflection is used absolutely everywhere in Java. It will simply not be possible for developer to restrict the packages they expose to prevent reflection. (The use cases where reflection really must be prevented are very few AFAICT) I'd also note that a large portion of the problem is due to the terrible Java beans approach (and the unwillingness of the team maintaining Java to address the problem of beans/properties over many years). Sadly my effort [1] has not gone anywhere, but a new API is really needed in this area to avoid all this ad-hoc and incompatible reflection of beans/properties. In summary, restricting reflection/setAccessible would effectively be signing the death warrant of Java, and there is IMO no choice but for all packages to be exported at runtime given the current ecosystem. Stephen [1] https://github.com/jodastephen/property-alliance
