Search code examples
javajavafx-8javacjava-9

Can not build javafx application under java 9 targeting java 8


I am trying to build an application which has a GUI built with JavaFX and targeting java 8 with java 9's new release flag.

Compiling

import javafx.application.Application;

public class Testing {
    public static void main(String... args) {

    }
}

when targeting java 9 with

javac Testing.java

works fine (also when using --release 9), but when I add the release flag

javac --release 8 Testing.java

it fails to compile giving does not exist errors

Testing.java:1:error: package javafx.application does not exist

There is no problem when compiling this under a JDK8 javac. I've tried using the --add-modules flag to add the jfx modules, but that flag is not allowed when setting a release to 8.

Is there a way to make this work under java 9? It seems that it doesn't think that the jfx packages are included with java 8, but they are (at least in oracle's release).

I am using the release version of java 9 on Windows, and have built the same application without problems under the most recent java 8 release.


I have tried to add the jfxrt.jar from my java 8 installation (and not rt.jar) to the classpath while compiling with the --release 8 flag, and it does work.

My understanding is that one purpose of the release flag was to remove the need to have multiple versions of the JDK installed (or at least their rt.jar files). I'm not sure if the intent was to only remove the need to compile against this one file, or if the intent was to remove the need to compile against any JDK packaged files (and jfxrt.jar is included with JDK8 [at least in Oracle's version] requiring no special flags or classpath modifications to use it).

Without being certain of the intent, it somehow seems wrong that something would compile perfectly under java 8 but would require an additional jar to compile (and only compile not run) under java 9 targeting java 8 (but not when targeting java 9), and thus requiring multiple JDKs. For anyone more familiar with the intended implementation of the release flag, should this be working this way?


Solution

  • The behaviour seems strange though in terms of how the --release flag internally resolved the required jdk internal classes. But owing to the fact that *rt.jars are removed in JDK9 and that javafx.application was a part of jfxrt.jar, it could be a probable reason why the same would complain about the missing package.


    The compiling section from migration guide though details this out that the --release N flag is conceptually a macro for:

    -source N -target N -bootclasspath $PATH_TO_rt.jar_FOR_RELEASE_N
    

    Hence it should work, if you try something like this for sure:

    javac -source 8 -target 8 -bootclasspath some/path/to/jdk1.8.0_65.jdk/Contents/Home/jre/lib/rt.jar Testing.java
    

    A simple solution in the replacement of above, of course, is to add the jfxrt.jar file to the classpath and then compile using the --release 8 flag.


    Note: Still leaves me puzzled why --release won't find the previous versions rt.jar? -- Might want to check for any such reported bugs.

    From comments:- JavaFX is considered an included extension in Java 8, so is not resolved when targeting version 8. Only the classes that would have been in the rt.jar file are resolved.