JDK 9 RFR of JDK-8072480: javac should support compilation for a specific platform version
jan.lahoda at oracle.com
Thu May 21 11:48:33 UTC 2015
Thanks for the comments.
On 21.5.2015 12:31, Maurizio Cimadamore wrote:
> Hi Jan,
> great work - couple of comments below:
> * it seems like some of the routines in Arguments can be simplified
> using lambdas - especially lookupPlatformProvider and checkOptionAllowed
Yes, I'll take a look.
> * Why JDKPlatformProvider is not called JDKPlatformProvider*Factory* ?
A remnant of history, I'll fix that.
> * JavacProcessingEnvironment.JoiningIterator seems to have commonalities
> with CompoundScopeIterator - any chance that we might refactor this a bit?
I'll take a look.
> * What's the rationale for giving an error if -platform is specified and
> a non-StandardFileManager is provided? Can't we simply swallow that,
> ignore the platform settings and issue a Lint 'options' warning?
If the bootclasspath cannot be set for -platform N, javac would be
compiling against the current version of the API, not against the N's
APIs. And so the result may not be able to run on N. So it seemed more
appropriate to me to refuse to continue rather than continue and produce
a potentially wrong result.
> * Would it make sense for some of the classfile generation logic in
> CreateSymbols to be moved under the classfile API ?
Possibly - the Classfile API could be made more friendly to create
classes from scratch. I'd prefer to keep that separate from this effort,
> * I had hard time reconciling some of the comments in CreateSymbols with
> how the files were laid out. I think in the end, what you mean is that
Ok - I'll work on making the comments more comprehensible.
> if you have platforms 7, 8, 9 - you should pick one baseline (i.e. 8)
> and then generate diffs for 9 and 7 against the 8 one. If that's the use
> case, I think the command line can be simplified a bit in order to
> explicitly state which of the platform is the baseline one, and the
> remaining parameters can be inferred from the tool (as the
> <base-platform-for-platform1,2 ... N> seem to be typically all identical
> but one which is set to <none> - the one for the baseline). Maybe the
> inference logic should be different (i.e. use 8 as a baseline for 7 and
> 7 as a baseline for 6) - but - whatever the logic, I think it should be
> chosen once and for all, and live implicitly in the tool? Or are there
> reasons as to why it might be handy to customize the baselines?
As an example, consider we would be currently storing data for 6, 7 and
8. We could have full 8 APIs stored, and then 8->7 diff and 7->6 diff.
So the baseline for 7 would be 8 and the baseline for 6 would be 7.
When the data for 9 would be added(*), we could keep the full APIs for 8
(to avoid wasting space in the repository), and then store 8->9 and 8->7
diffs (and drop 6). So 8 would be the baseline for both 7 and 9. So,
some flexibility may be useful here.
Does this make some sense?
(*) For JDK 9, there are no history data stored for 9, -platform 9 uses
the real JDK 9's bootclasspath (for JDK 9, -platform 9 is mostly a
no-op). We would presumably add the history data for 9 when JDK 9 is
> On 21/05/15 08:01, Jan Lahoda wrote:
>> This is a patch adding a new option, -platform, to javac.
>> Patch for the top-level repository is here:
>> Patch for the langtools repository is here:
>> These changes also require additional langtools changes as their
>> Overall, one can imagine '-platform N' to have the same effect as
>> '-source N -target N -bootclasspath <APIs-for-N>'. The possible values
>> for 'N' are pluggable in a limited way, though (see
>> Note that this patch only introduces N=7 and N=8, which correspond to
>> Open JDK 7 and 8 GA.
>> A tricky problem to solve is where to get the APIs for platform N. The
>> proposal is to include history data in the textual format inside the
>> OpenJDK repositories (the input data), process them at build time and
>> create a lib/ct.sym file holding the data in the JDK image. javac
>> running with the -platform option then compiles against the lib/ct.sym
>> file. The input history data are placed
>> <top-level-repository>/make/data/symbols (the sym.txt files). This
>> patches only includes data for OpenJDK 7 and 8, and only for public
>> APIs (more or less Java SE and JDK @Exported APIs).
>> The size of the history data is currently ~6MB in the JDK checkout and
>> ~650kB inside the .hg directory (the size could change significantly
>> if additional classes/elements, like non-public API classes, would
>> need to be included). The lib/ct.sym file is currently ~4.5MB.
>> The ct.sym file is a zip file containing signature files. The
>> signature files are similar to classfiles (so javac can read them as
>> classfiles), but are missing some attributes, most notably the Code
>> attribute. On the top-level, the ct.sym contains directories named
>> "7", "78" and "8". When compiling for version 'N', the bootclasspath
>> for that version is obtained by using directories which have 'N' in
>> their name.
>> The sigfiles for ct.sym are created by
>> The same file can also be used to construct the sym.txt files. Concise
>> instructions are part of the CreateSymbols.java.
>> I am sending this as one review, as the changes together make one
>> feature, but the langtools and top-level changes are independent to a
>> great degree: the langtools changes add the "-platform" javac; and the
>> top-level changes add the history data and ability to build the ct.sym
>> file. If desired, these could be pushed and/or reviewed independently.
>> Many thanks go to Jon Gibbons, Joe Darcy, Magnus Ihse Bursie, Alan
>> Bateman and others who have provided advices and help on the matter
>> Any insights/comments are wholeheartedly welcome.
More information about the build-dev