Suggestion: allow accessible reflection on protected methods of exported types.
Alan.Bateman at oracle.com
Tue Jan 3 16:28:41 UTC 2017
On 29/12/2016 16:24, Rafael Winterhalter wrote:
> I argue that this module system should not be responsible to assert the
> usage of such protected methods on exported types. Such methods are not
> really encapsulated as they are considered official API by subclasses.
Right, they are intended to be used by sub-classes and this hasn't
changed, meaning that you should have no issue accessing a protected
member defined in the super class with bytecode or core reflection as
before (no setAccessible in the picture).
With strong encapsulation then having setAccessible treat protected
members as public would mean we would be back to the hole that is
#AwkwardStrongEncapsulation. It would mean anyone could access protected
members that are not intended to be accessed in this way. Also in the
case of the core modules then it conflicts with the goal to mprove
As regards the change you are seeing now then it has been in the Jigsaw
EA builds for some time but only merged into the JDK 9 builds at
jdk-9+148. There is further spec work required to deal with
protected-static and protected constructors but that is a topic for
another thread. There is of course a compatibility impact with this
change. It will expose many hacks, a number of them have come up on this
mailing list already. It will also impact code that relies on being able
to use setAccessible to get at protected-instance methods that it would
not otherwise have access to in bytecode.
For mitigation then the `--add-opens` command line option can be used to
open any package of any module and so can be used to keep existing code
working. Ideally of course this would not be needed but it requires
effort from the maintainers of many important libraries and tools.
There has been an outreach effort going on for the last 2+ years to try
to get an many projects and libraries working with us so that the eco
system will be in reasonable shape by the time that JDK 9 ships. In
general then JDK 9 is very different to past releases in that it comes
with many disruptive changes and requires updates across many areas of
the eco system before it is generally usable by the average developer.
As regards defineClass then I see you've found Unsafe::defineClass. Many
important libraries in the eco system rely on Unsafe and it will
continue to be accessible in JDK 9. All the details on that are in JEP
260. Long term then Unsafe needs to go away of course and that will
require working on some challenging use-cases. The VarHandles work in
JEP 193 is a huge step forward but there are several other areas that
will need effort. Using Unsafe::defineClass might feel like a regression
but I'm not aware of any current efforts that would result in a "safe"
way to do this type of injection (say a restricted defineClass that
would only allow injecting into open packages for example).
One final point about ClassLoader::defineClass is that java agents and
tools doing bytecode instrumentation have the power to redefine modules
and classes and so can break into all modules. I guess you are very
familiar with this already.
More information about the jigsaw-dev