We are currently planning on adding support for JEP 220, commonly known as "Jigsaw", to Fantom in the next release. Jigsaw restructured the entire JDK and JRE runtime images into "modules". This feature was released in Java9. As part of this work, we intend to make a few changes to the build environment for Fantom, and would like community feedback on these changes.
Note: for the rest of this post when I specify Java9, I really mean "Java9 or any later version".
History
Currently, Fantom can only be built with JDK 1.8, and we target the bytecode and API for Java 1.7. This behavior is specified by the javacParams defined in etc/build/config.props
javacParams=-source 1.7 -target 1.7
Additionally, when compiling Fantom pods that contain Java natives, the build::CompileJava task internally sets an additional parameter for javac to specify the -bootclasspath to point to JDK 1.8 rt.jar. This process is called cross-compilation (i.e. using a later version of Java to target an earlier version).
So, today you can run Fantom code with any version of Java (including Java9), but you cannot use Java9 to compile Fantom code that uses JavaFFI. When we add support for Jigsaw, you will be able to do this.
Proposed Changes
The proposed changes only impact development environments. They will allow us to build Fantom code that uses JavaFFI using Java9.
First, we plan to require Java9 (or higher) to build Fantom code. The reason for this change is that we would like to standardize on using the new module class system in Jigsaw. It will also help to simplify the code base and make it more maintainable since we won't have to handle two code paths for compiling with pre-Jigsaw and post-Jigsaw JDKs.
Second, we plan to go ahead and make the change to target Java 1.8 APIs and bytecode as part of this work. We will do this by changing the javacParams in etc/build/config.props to
javacParams=--release 8
The --release option is new in Java9, and specified in JEP 247. It has the following effect:
We defined a new command-line option, --release, which automatically configures the compiler to produce class files that will link against an implementation of the given platform version. For the platforms predefined in javac, --release N is equivalent to -source N -target N -bootclasspath <bootclasspath-from-N>
It is important to note that even with these changes, you will still be able to run Fantom code using Java 1.8.
Summary
To summarize the proposed changes:
We will require Java 9 (or higher) to build Fantom code that uses JavaFFI, or has Java native code (since we are using new --release option).
We will target Java 1.8 bytecode and APIs
Therefore, we will require a Java 1.8 JRE to run Fantom code
Your feedback and comments are appreciated.
jhughesThu 9 May 2019
I recently needed to integrate some java 11 code into a fantom installation and ran into the java 8 limit and had to do a fair amount of refactoring to get it to work so I am all in favor of getting fantom past java 8.
The question I would have is how does this runtime vs compile time effect imported jars? In the scenario I described, it was an imported jar compiled at java 11 so would this proposed change also allow jars compiled at higher than java 8 or would third party jars still be restricted to java 8 because of runtime restrictions?
matthewThu 9 May 2019
@jhughes
The question I would have is how does this runtime vs compile time effect imported jars?
If you have Java 11 jars, then you will need a Java11+ JRE.
If you are writing Fantom code that uses JavaFFI to reference types or APIs introduced after Java 1.8, or you have native Java code in a Fantom pod that needs newer APIs, then you will have to edit the etc/build/config.props and change
javacParams=--release 11
You have effectively made your pod dependent on Java 11. Whereas, by default, Fantom is targeting Java 1.8 runtime.
matthewWed 22 May 2019
I just wanted to follow-up on this design proposal to talk about the final implementation - which has a few changes.
First, we just released Build 1.0.73 which contained the necessary bootstrap changes that we needed so that we could then introduce the actual support for Jigsaw.
Today I pushed a changeset that adds support for compiling Fantom code with Java9+. When we do the next build (1.0.74), you will be able to do that.
Originally, we thought we would require Java9 or higher when we made this change, but we have been able to preserve the existing behavior in a fairly elegant way which will allow you to compile with either Java8 or Java9+. The default Fantom release will still be configured (for now) to compile using Java8 and target 1.7. There are plans later this year to target 1.8, but for now the behavior is exactly the same.
Let me know if you have any questions.
AlexMWed 22 May 2019
@matthhew Thanks for your work.
You write "JDK9+" but since JDK 9 and JDK10 are out of support by now, I would rather target JDK 11+ and use this term officially.
Now JDK 11 being the LTS, what would it mean in term of effort to produce releases for JDK 11 LTS (during it whole lifespan) and have the master releases all/some (tbd) non LTS Versions until JDK 17 (next LTS) ?
Industry is about the opt-in for the LTS version (I cannot believe they will follow Oracle's 6 month cycles, at least not my company ;-)).
The next point to face is.. which JDK ??
AdoptOpenJDK seems to be (currently) the better choice
Oracle OpenJDK
Redhat OpenJDK
Amazon Corretto
...
matthewWed 22 May 2019
Hi Alex - I've been using "Java9+" to signify the more broad term of "Jigsaw" JDKs (Java9+). But you are right, realistically I have in view the LTS versions of the JDK. I myself have been testing with JDK 11 for this very reason.
The broader point of all this is that prior to these enhancements you could not compile Fantom code with Java9+, and now you can.
However, please note that for the foreseeable future we will continue to "target" Java7 (and soon Java8) bytecode and APIs. You will be able to compile with the latest Jigsaw JDKs, but there are too many legacy platforms and devices out there to default to the latest Jigsaw LTS JDK for bytecode and API.
matthew Thu 9 May 2019
We are currently planning on adding support for JEP 220, commonly known as "Jigsaw", to Fantom in the next release. Jigsaw restructured the entire JDK and JRE runtime images into "modules". This feature was released in Java9. As part of this work, we intend to make a few changes to the build environment for Fantom, and would like community feedback on these changes.
Note: for the rest of this post when I specify Java9, I really mean "Java9 or any later version".
History
Currently, Fantom can only be built with JDK 1.8, and we target the bytecode and API for Java 1.7. This behavior is specified by the
javacParams
defined inetc/build/config.props
Additionally, when compiling Fantom pods that contain Java natives, the
build::CompileJava
task internally sets an additional parameter forjavac
to specify the-bootclasspath
to point to JDK 1.8 rt.jar. This process is called cross-compilation (i.e. using a later version of Java to target an earlier version).So, today you can run Fantom code with any version of Java (including Java9), but you cannot use Java9 to compile Fantom code that uses JavaFFI. When we add support for Jigsaw, you will be able to do this.
Proposed Changes
The proposed changes only impact development environments. They will allow us to build Fantom code that uses JavaFFI using Java9.
First, we plan to require Java9 (or higher) to build Fantom code. The reason for this change is that we would like to standardize on using the new module class system in Jigsaw. It will also help to simplify the code base and make it more maintainable since we won't have to handle two code paths for compiling with pre-Jigsaw and post-Jigsaw JDKs.
Second, we plan to go ahead and make the change to target Java 1.8 APIs and bytecode as part of this work. We will do this by changing the
javacParams
inetc/build/config.props
toThe
--release
option is new in Java9, and specified in JEP 247. It has the following effect:It is important to note that even with these changes, you will still be able to run Fantom code using Java 1.8.
Summary
To summarize the proposed changes:
--release
option).Your feedback and comments are appreciated.
jhughes Thu 9 May 2019
I recently needed to integrate some java 11 code into a fantom installation and ran into the java 8 limit and had to do a fair amount of refactoring to get it to work so I am all in favor of getting fantom past java 8.
The question I would have is how does this runtime vs compile time effect imported jars? In the scenario I described, it was an imported jar compiled at java 11 so would this proposed change also allow jars compiled at higher than java 8 or would third party jars still be restricted to java 8 because of runtime restrictions?
matthew Thu 9 May 2019
@jhughes
If you have Java 11 jars, then you will need a Java11+ JRE.
If you are writing Fantom code that uses JavaFFI to reference types or APIs introduced after Java 1.8, or you have native Java code in a Fantom pod that needs newer APIs, then you will have to edit the
etc/build/config.props
and changeYou have effectively made your pod dependent on Java 11. Whereas, by default, Fantom is targeting Java 1.8 runtime.
matthew Wed 22 May 2019
I just wanted to follow-up on this design proposal to talk about the final implementation - which has a few changes.
First, we just released Build 1.0.73 which contained the necessary bootstrap changes that we needed so that we could then introduce the actual support for Jigsaw.
Today I pushed a changeset that adds support for compiling Fantom code with Java9+. When we do the next build (1.0.74), you will be able to do that.
Originally, we thought we would require Java9 or higher when we made this change, but we have been able to preserve the existing behavior in a fairly elegant way which will allow you to compile with either Java8 or Java9+. The default Fantom release will still be configured (for now) to compile using Java8 and target 1.7. There are plans later this year to target 1.8, but for now the behavior is exactly the same.
Let me know if you have any questions.
AlexM Wed 22 May 2019
@matthhew Thanks for your work.
You write "JDK9+" but since JDK 9 and JDK10 are out of support by now, I would rather target JDK 11+ and use this term officially.
Now JDK 11 being the LTS, what would it mean in term of effort to produce releases for JDK 11 LTS (during it whole lifespan) and have the master releases all/some (tbd) non LTS Versions until JDK 17 (next LTS) ?
Industry is about the opt-in for the LTS version (I cannot believe they will follow Oracle's 6 month cycles, at least not my company ;-)).
The next point to face is.. which JDK ??
matthew Wed 22 May 2019
Hi Alex - I've been using "Java9+" to signify the more broad term of "Jigsaw" JDKs (Java9+). But you are right, realistically I have in view the LTS versions of the JDK. I myself have been testing with JDK 11 for this very reason.
The broader point of all this is that prior to these enhancements you could not compile Fantom code with Java9+, and now you can.
However, please note that for the foreseeable future we will continue to "target" Java7 (and soon Java8) bytecode and APIs. You will be able to compile with the latest Jigsaw JDKs, but there are too many legacy platforms and devices out there to default to the latest Jigsaw LTS JDK for bytecode and API.