#2743 Jigsaw Support in Fantom

matthew Thu 9 May

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:

  1. 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).
  2. 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.

jhughes Thu 9 May

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

@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.

Login or Signup to reply.