Suggestion: allow accessible reflection on protected methods of exported types.

Alan Bateman 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 
platform integrity.

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.

-Alan.


More information about the jigsaw-dev mailing list