Widespread use of reflection, [was Feedback on proposal for #ReflectiveAccessToNonExportedTypes]

Alessio Stalla alessiostalla at gmail.com
Wed Jul 27 11:41:51 UTC 2016


+1 to that. And kudos for gathering all those uses of setAccessible.

On 27 July 2016 at 13:28, Stephen Colebourne <scolebourne at joda.org> wrote:

> On 13 July 2016 at 22:47,  <mark.reinhold at oracle.com> 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
>


More information about the jigsaw-dev mailing list