6

I am trying to compile with JDK 11 but target Java 1.8 in IntelliJ. I have configured:

  • Project Settings:
    • Project SDK: 11
    • Project language level: 8
  • Java Compiler Settings:
    • Use '--release' option for cross-compilation (Java 9 and later)
    • Project bytecode version: 8
  • Module Settings:
    • Project SDK (11)
    • Language level: Project default (8 - Lambdas, type annotations etc.)

I get a bunch of compilation errors saying that internal packages do not exist. --add-exports is not valid with --target 1.8 so that doesn't help.

The only thing that does work is to set the Project SDK back to Java 1.8 (which causes other problems when trying to run with Java 11 but that is another issue).

Is it possible to compile with JDK 11 and target Java 1.8 in IntelliJ?

There are other related questions which seem to work but not from IntelliJ:

steinybot
  • 5,491
  • 6
  • 37
  • 55
  • Do you have `module-info.java` files in the project? I can't reproduce the problem, project builds just fine with 8 target (bytecode). You may need to share the [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve) to get help. – CrazyCoder Apr 10 '19 at 02:06
  • @Matt This is definitely not a duplicate of that issue. I already said that I have set the project bytecode version to 8 so that answer does not answer this. – steinybot Apr 10 '19 at 22:33

1 Answers1

7

Unfortunately, you can't use internal APIs if you compile with the --release N option. This is described in JEP 247:

A new command-line option, --release, is defined, which automatically configures the compiler to produce class files that will link against an implementation of the given platform version. --release N is roughly equivalent to:

for N < 9: -source N -target N -bootclasspath <documented-APIs-from-N>,

for N >= 9: -source N -target N --system <documented-APIs-from-N>.

And then follows the main paragraph:

For N < 9, the documented APIs consist of the public APIs that were on javac's default bootclasspath for JDK N.

I agree this is a big limitation actually. You can't even use sun.misc.Unsafe which has always been a critical part of OpenJDK.

So, your question has nothing to do with IntelliJ IDEA. It's a limitation of the Java platform.

You have two ways:

  • Don't use internal APIs
  • Use JDK 8 for compilation
ZhekaKozlov
  • 36,558
  • 20
  • 126
  • 155
  • Ah thanks. I didn't look at it closely enough to see that it was only the "documented-APIs-from-N". I thought the whole point of it was to allow this to work. Oh well, JDK 8 it is then I guess. – steinybot Apr 10 '19 at 22:39
  • What if `--release` option is not used, only `-source/-target`? – CrazyCoder Apr 17 '19 at 03:15
  • @CrazyCoder In that case, javac will use the API of the running JDK. This may be dangerous since you can accidentally use the API that didn't exist in JDK 8. – ZhekaKozlov Apr 17 '19 at 03:40