converting javac to be a modular app
Mandy Chung
mandy.chung at oracle.com
Wed May 26 10:05:12 PDT 2010
On 05/26/10 09:33, Jonathan Gibbons wrote:
> Comments inline.
>
> -- Jon
>
>
> On 05/26/2010 09:20 AM, Mandy Chung wrote:
>> Jon,
>>
>> This note is helpful and it gives an idea how complicate the world we
>> are in! My comment inlined below.
>>
>> On 05/24/10 19:25, Jonathan Gibbons wrote:
>>> On the face of it, it ought to be easy to change javac to be
>>> executed with module mode instead of legacy mode. You might think it
>>> is sufficient to simply remove the reference to -J-Xmode:legacy in
>>> the appropriate line of jdk/make/launchers/Makefile, as in the
>>> following diff:
>>>
>>>> $ hg diff -U 0
>>>> diff -r 7e1d7e037819 make/launchers/Makefile
>>>> --- a/make/launchers/Makefile Mon May 24 14:27:31 2010 -0700
>>>> +++ b/make/launchers/Makefile Mon May 24 16:43:30 2010 -0700
>>>> @@ -64,1 +64,1 @@
>>>> -$(call make-launcher, javac, com.sun.tools.javac.Main,
>>>> -J-Xmode:legacy, )
>>>> +$(call make-launcher, javac, com.sun.tools.javac.Main, , )
>>>
>>> If only it were that simple ...
>>>
>>> To understand the real problem, you need to understand javac's role
>>> in building JDK. For a full description of the build process, see
>>> Kelly's blog, "Anatomy of the JDK Build":
>>> http://blogs.sun.com/kto/entry/anatomy_of_the_jdk_build
>>>
>>> Here's a quick summary:
>>>
>>> 1. Build the latest javac with the BOOTJAVA javac to create a hybrid
>>> javac (call it hybrid-1) that can run on BOOTJAVA but which can
>>> compile JDK7 code.
>>> 2. Use hybrid-1 javac to compile all the langtools repository for
>>> delivery into the final bundles.
>>> 3. Use hybrid-1 javac to compile the corba, jaxws, jaxp, repositories
>>> 4. Build the jdk repository using hybrid-1 javac, and including all
>>> the classes compiled in steps 1, 2 and 3, to produce candidate JDK
>>> bundles.
>>>
>>> Many developers stop at this point. But up to this point, the JDK
>>> created in step 4 has not been tested, so a common step is to
>>> perform the build with SKIP_BOOT_CYCLE=false. If that variable is
>>> set, the build will repeat steps 1-4 using the JDK from step 4 (call
>>> it "interim JDK") as the setting for BOOTJAVA.
>>>
>>> 5. Build the latest javac with the interim JDK javac to create a
>>> hybrid javac (call it hybrid-2) that can run on the interim JDK and
>>> which can compile JDK7 code.
>>> 6. Use hybrid-2 javac to compile all the langtools repository for
>>> delivery into the final bundles.
>>> 7. Use hybrid-2 javac to compile the corba, jaxws, jaxp, repositories
>>> 8. Build the jdk repository using hybrid-2 javac, and including all
>>> the classes compiled in steps 1, 2 and 3, to produce final JDK bundles.
>>>
>>> So where's the problem? Not surprisingly, it's in those hybrid-1
>>> and hybrid-2 versions of javac. Currently, we synthesize those
>>> hybrid versions of javac by using -J-Xbootclasspath/p: to override
>>> the location of the javac classes being used by the underlying JDK.
>>> As long as we build javac to execute in legacy mode, that works just
>>> fine. But once we switch javac to use module mode, we lose the
>>> ability to use -J-Xbootclasspath/p:. Instead, we have to use the
>>> new "-L library" option, which replaces "-Xbootclasspath/p:classes".
>>> What does that entail?
>>>
>>> Currently, there is no explicit artifact that is identifiable as
>>> "hybrid-1" or "hybrid-2" javac. Instead, the langtools part of the
>>> build delivers a set of classes, to be used as part of a hybrid
>>> javac, and each downstream repository in the forest uses those
>>> classes with -J-Xbootclasspath to synthesize the hybrid javac. So,
>>> there are two sets of changes to be made.
>>> - The langtools repository must determine if it has been given a
>>> legacy JDK or a modular JDK for its bootstrap. If it has been given
>>> a modular JDK, it needs to create a module library to be used for
>>> downstream compilations.
>>> - All downstream builds need to determine if they have been given a
>>> legacy JDK or a modular JDK for their bootstrap, and so should
>>> synthesize their hybrid javac using "-Xbootclasspath/p:classes" or
>>> "-L library" (or rather, "-J-Xbootclasspath/p:classes" or "-J-L
>>> -Jlibrary". Mild uugh!)
>>>
>>> Note that we cannot hard-code the change to use "-L library" through
>>> the life of JDK7. In other words, for as long as we need to start
>>> the build using a legacy JDK, such as JDK 6, the build must be
>>> "bimodal", able to work with both a legacy JDK, or a modular JDK
>>> such as may just have been built.
>>>
>>> The changes to have the langtools repository build a module library
>>> are essentially as described here:
>>>
>>> http://mail.openjdk.java.net/pipermail/jigsaw-dev/2010-May/000960.html
>>>
>>> However, the changes described there concerned a developer build of
>>> javac; the changes need to be replicated to apply to the bootstrap
>>> builds as well. This corresponds to langtools having settings for
>>> two different versions of JDK -- one to build with, and one to
>>> execute what it builds: the langtools build needs to be prepared for
>>> each setting to be given either a legacy JDK or a modular JDK.
>>>
>>> The changes to have each downstream repository determine whether to
>>> use -Xbootclasspath or L are not particularly difficult. One minor
>>> complication to take into account is that some repositories use Ant
>>> instead of "make". Another complication is whether or not this
>>> needs to be a synchronized build change across all repositories. One
>>> way to avoid that would be a two phase approach, such that we first
>>> change all repositories to explicitly force the use of legacy mode
>>> for javac, then we can change the default mode for javac, then
>>> finally update the repositories to work with the default.
>>>
>>
>> I think the javac would have to stay in legacy mode for jdk build for
>> some time until the jdk compiles classes in its module directory
>> (i.e. setting -modulepath for javac to use). In step 4 & 8
>> (building jdk), the hybrid javac overrides the bootclasspath with the
>> classes directory as it compiles itself. The module library for the
>> jdk is created at the end of the jdk build. It can use -L option to
>> set to use the langtools module library but it still needs a way to
>> compile jdk sources with the newly built classes during the jdk build.
>
> Ah, but that's the "other" bootclasspath, isn't it? The hybrid
> javac's are all about the use of the JVM bootclasspath, and changing
> to set the JVM module library. Here, you're talking about the javac
> bootclasspath and -L option.
>
That's right - that's the other bootclasspath! JDK will continue to
compile in single module mode (i.e. legacy compilation) with javac's
-Xbootclasspath option. javac will run with the latest langtools
classes via the JVM bootclasspath or JVM module library (the -J
version). I clearly mixed them up when I first read this but now it's
clear. Thanks.
>
>>
>> What steps would you imagine it takes to update the langtools repo to
>> work with the default? I guess langtools can remain being compiled
>> in single module mode using the -sourcepath option? It doesn't
>> require langtools to be compiled as modules for phase 2. I try to
>> put things together in my head - do I get this right?
>>
>>> That's almost it. You'd think.
>>>
>>> If only it were that simple ...
>>>
>>> Who spotted that sometimes developers perform "partial builds" and
>>> don't necessarily use and build a copy of the langtools repository?
>>> Instead, you can set ALT_JDK_IMPORT_PATH to a recent build of JDK.
>>> So yes, we need to make the build work in that case as well. And,
>>> for now, that is left as an exercise for the reader.
>>>
>>
>> That's a good point. If ALT_JDK_IMPORT_PATH would be a modular JDK,
>> the current workaround is to copy classes directly from the imported
>> module library. The jdk makefiles have be modified to import corba,
>> jaxp and jaxws from a modular JDK but yet to import langtools correctly.
>
> Hmmm, yes, I was just thinking of the javac bootstrap issues; I
> missed the need to import classes from the ALT_JDK_IMPORT_PATH.
>
>>
>> In the long-term, I think the jdk build would import from the
>> langtools module files (and other components) from a promoted build
>> rather than a module image.
>
> What is the difference that you're thinking of here?
>
It's related to the jdk partial build issue and how it should import
components in the modular world. I wanted to point it out as langtools
will be building jmod files that would work well in the future.
ALT_JDK_IMPORT_PATH refers to a JDK image. In the legacy world, we build
only the legacy image and thus we can only import from a JDK image
(that's ALT_JDK_IMPORT_PATH). In the modular world, we will bundle the
jdk module files in addition to the jre-base-image. For doing a partial
jdk build (no langtools build), some time later the jdk build should
support to import from the jdk module files (e.g. javac.jmod,
corba.jmod, etc).
>
>
> In the short term, my plan is to push changes that will have the
> langtools build create modules from the langtools bootstrap classes
> for optional use downstream if desired. We can then work on
> determining how to use those modules in the downstream repos.
>
Sounds good.
Mandy
More information about the jigsaw-dev
mailing list