On 03.01.2017 17:28, Alan Bateman wrote:
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).
Alan, can you please give me a relevant example where it makes sense for
a subclass to invoke a super class protected method by reflection rather
than by direct invocation? The case of "you should have no issue
accessing a protected member defined in the super class with [...] core
reflection" sounds awfully constructed. Especially since reflection does
not do invokespecial but invokevirtual logic, which means if the
subclass overrides the method, the override will be called instead of
the super class member.
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.
you could access protected members in exported classes, yes. But it
would help the application compatibility.
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.
I there is still time for that?
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.
not have access otherwise means the class is final, afaik. Are there any
other cases?
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.
We had many, many discussion on this list as of why this is problematic.
By now you need so many --add-opens, that you have to put them in a file
to not exceed maximum command line length. And it means a container will
need a JVM restart to be able to give the "module" all functionality if
it requires adding an opens. I see this for example as a problem for
tomcat. This could of course be made more easy if you could just open
all modules, but this was silently rejected. And for something like
scripting this stuff is extremely bothersome. I am not sure there are
even solutions to all cases.
But from the lengthy and rarely fruitful discussions here I also get
that jigsaw is supposed to be a breaking change.
Ideally of course this would not be needed but it requires
effort from the maintainers of many important libraries and tools.
You sound as if there are equal good alternative solutions to all these
cases. For example changing the environment for a subprocess after its
creation.... No, there is no clean solution. The only solution that does
not require an opens is to do it by custom native code.
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.
shortly before the last Java One things changed majorly with
#AwkwardStrongEncapsulation. If we would still have the same situation
we had 5 months ago I would have been much more happy. But then again
this thread here would probably not have come into existence as well.
You know the funny part about #AwkwardStrongEncapsulation is that I
think it was supposed to say that the old encapsulation was awkward...
but for me it means the new one is.
[...]
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.
I prognose a different solution... A custom application loader that will
be able to dynamically load modules and will add opens to all of them,
plus a big list of add-opens on startup for all the JDK stuff. That
means the only not-core module the JVM would start with is the module
that opens all the modules.
bye Jochen