Hi Stephen, ----- Mail original ----- > De: "Stephen Colebourne" <scolebou...@joda.org> > À: "jigsaw-dev" <jigsaw-dev@openjdk.java.net> > Envoyé: Lundi 16 Novembre 2015 13:28:22 > Objet: Re: A way to opt out of access restrictions on non-exported members. > > Access to private members of classes by reflection is indeed very, > very common. I agree that JDK 9 needs to be cautious around this. > > For me, I'm not yet sure I'm comfortable with setAccessible(true) no > longer being sufficient to access them. > > I did wonder if perhaps a change could be made such that any instance > of 'Class' passed into a module would automatically be granted the > necessary enhanced module readability. Unfortunately, I don't think it > will be enough for most serialization frameworks, as they traverse a > graph of objects.
We discuss something like this at Devoxx, add a read edge between the current module and the module of the declaring class when you do a setAccessible on a member of that class. This will not solved all the issues, frameworks will still not be able to call setAccessible on a non exported class but i think it will fix most of the issues if (and it's a big if) creators of modules do not allow non-exported classes to leak. > > I do think that there may need to be separate JDK 8 and 9 versions of > many OSS libraries (for which the multi-version jar file is one > option). This will certainly slow adoption. > > Stephen Rémi > > > > On 15 November 2015 at 11:03, Reinier Zwitserloot > <rein...@zwitserloot.com> wrote: > > TL;DR: There are rather a lot of libraries out there that access private > > members via reflection. I posit that almost all such libraries break > > without an easy way to fix the problem, if there is no way to use > > reflection to access non-exported members. > > > > > > > > setAccessible(true) doesn't let you opt out of module access rules. There > > are ways to effectively 'read' everything (and if not, there's addRead), > > but that still doesn't help if you need to reflectively access a member > > that isn't exported. According to the questions at the end of the J1 > > session 'Advanced Modular Development (CON6821)', by Mark Reinhold, Alex > > Buckley, and Alex Bateman, there is no way to in-process get around the > > JVM-enforced access restriction. > > > > Now, under normal circumstances you shouldn't be accessing such classes / > > methods / fields / constructors in the first place, but that exact same > > line of reasoning can be used to defend not including setAccessible, > > getDeclaredMethod(s), getDeclaredField(s), and all the other ways the > > reflection API can be used to access (in JDK1-JDK8, at least) protected, > > package private, and private elements. Those things were never designed to > > be accessed either, and yet, accessing private members of existing stuff > > occurs in lots of libraries, usually for: > > > > * Dependency injection (guice and company) > > > > * Debugging tools (not all of these use JVMTI; sometimes you just have a > > utility method that dumps some information to a log that includes private > > members just because that seems like it'll help debug an exotic condition > > that you can't quite put your finger on). > > > > * Code automation tools (apache has a few utilities that return a useful > > hashCode, which work by inspecting your instance's fields). > > > > * Serialization libraries. I'm pretty sure a number of core JDK devs have > > gone on record not liking the built in serialization mechanism > > (java.io.Serializable and co), but third party solutions access private > > members all the time to do their job. > > > > * Workarounds. This one is a perhaps controversial, but as the saying goes, > > java is a 'blue collar' programming language. Sometimes you use access to > > private members to work around a bug or to get access to functionality that > > optimally speaking should be done differently or should be accomodated with > > an update to the library to make that part designed for public access. > > > > What are such libraries to do? They could provide the user with ways to use > > command line switches to hack in the required exports, but this is the kind > > of hassle that is going to reflect badly on JDK9 and slow adoption rates. I > > propose some mechanism to get around the restriction is added, with all due > > warnings in the documentation that this should be considered a hacky > > workaround. (interestingly, such commentary is not part of the javadoc on > > .setAccessible!) > > > > Alternatively, there are 3 ways this can go: > > > > * The authors of these libraries, or the help forums associated with such > > libraries, start espousing the principle that you should just export > > everything from your modules, or 'things might break'. This doesn't sound > > like a desirable outcome for the jigsaw project. It certainly doesn't sound > > desirable to me. > > > > * The authors of these libraries, or the help forums associated with this > > libraries, start espousing the principle that upgrading to JDK9 is an > > arduous slog, and that it is better to just stick with JDK8 for the > > foreseeable future. Certainly, not a desirable outcome. > > > > * The heavens part, ponies and rainbows for all, and everyone takes the > > time to update their serialized data structures or whatnot to make sense in > > a 'these are exported, these are not' world. I'm not sure this is even > > possible; it would make sense to have a public interface, and then 2 > > (non-exported!) classes that are implementations of this. How would a > > no-hassle serialization library ever get this done without a way to dodge > > the rules? A module can export _TO_ a serialization library, but this > > breaks encapsulation: Now the author of framework A needs to know that the > > user of said framework so happens to have a desire to serialize the stuff > > from framework A using serialization library X. In practice you'd have to > > export everything to all the serialization frameworks out there, and now no > > new framework can ever be created because all these libraries failed to > > export their internals to them. In any case this boils down to 'just export > > every package to this subset of tools', and that's the best case scenario, > > which doesn't sound desirable either. > > > > I guess option 4 is: "Surely it won't be that bad", but that's a bit of a > > gamble to make, given that the stakes are serious lack of adoption of JDK9, > > or widespread misconfiguration of exports clauses. > > > > NB1: Note also that JDK9 has taken its time (and rightly so) to fix its > > ball-o-twine dependency mess. However, once JDK9 is unleashed upon the > > masses, a 'quick fix' to make libraries at least workable with JDK9 > > probably require such hacks. If it's not possible to do it, then libraries > > won't be JDK9 ready for years. Perhaps other projects aren't as messy as > > JDK pre-9 was, but let's not make that assumption. > > > > NB2: The module system already has a larger impact on adoption (compared to > > 6, 7, or 8) simply because of the unavoidable differences inherent in what > > jigsaw is doing (I bet a bunch of command line scripts are going to end up > > breaking, for example, or at least will be obsolete). Adding more barriers > > to adoption is something that should, in my opinion, by taken particularly > > seriously for this release. > > > > --Reinier Zwitserloot >