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. 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 PS. I'm reminded of Java's missing "properties" feature again, cf. http://jodastephen.github.io/property-alliance/ 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