2

I have multiple JDKs installed.

In my build.gradle, I set sourceCompatibility = 1.8 to ensure the right one is used. This works fine.

However, this seems to be ignored by the Javadoc task (./gradlew javadoc), which fails with an error (error: package sun.net.www.protocol.http is not visible) -- from this question I learned that this is an issue with a new feature in Java 9.

As of now, the project is aimed at Java 8 only. One day it will be upgraded to Java 9, but not today, so I just want to use the Java 8 javadoc generator instead of the Java 9 version.

I checked the task documentation but it doesn't look like there's any option to specify a JDK version. What can I do?

I'm expecting the solution to be a Gradle configuration, so it can be easily shared with the other devs on different machines.

Gradle version in which the behavior was seen (installed through IntelliJ):

------------------------------------------------------------
Gradle 4.4
------------------------------------------------------------

Build time:   2017-12-06 09:05:06 UTC
Revision:     cf7821a6f79f8e2a598df21780e3ff7ce8db2b82

Groovy:       2.4.12
Ant:          Apache Ant(TM) version 1.9.9 compiled on February 2 2017
JVM:          10.0.1 (Oracle Corporation 10.0.1+10-Debian-4)
OS:           Linux 4.16.0-2-amd64 amd64

Gradle version in which there was a warning instead of a failure of the Javadoc task (installed through Debian's repos):

------------------------------------------------------------
Gradle 3.4.1
------------------------------------------------------------

Build time:   2012-12-21 00:00:00 UTC
Revision:     none

Groovy:       2.4.15
Ant:          Apache Ant(TM) version 1.10.3 compiled on June 13 2018
JVM:          10.0.1 (Oracle Corporation 10.0.1+10-Debian-4)
OS:           Linux 4.16.0-2-amd64 amd64

Edit -- I have found this page that specifies that a "-source release" parameter that is probably the solution to this problem, however I cannot find the way it should be called:

javadoc {
    options.addStringOption('-source', '8')
}

This compiles & runs with no warnings (in build.gradle), but doesn't change anything and doesn't appear in /build/tmp/javadoc/javadoc.options.

CLOVIS
  • 771
  • 8
  • 24
  • In case it wasn't clear, tasks such as 'build' or 'test' work fine without errors on the JDK8 as expected. It's only the Javadoc task that fails. – CLOVIS Jul 02 '18 at 12:18
  • Setting the source compatibility doesn't select a JDK. As you see in your output, you're using Java 10.0.1. Gradle uses the Java version that is in your PATH. – JB Nizet Jul 04 '18 at 14:53
  • Both Java 8 & Java 10 are in my PATH. I want the javadoc doclet to run with Java 8 because some features (like the HTTP classes) were changed in Java 9 – CLOVIS Jul 04 '18 at 15:39
  • You shouldn't have two different versions of the JDK in your path. The first one will be picked anyway. – JB Nizet Jul 04 '18 at 15:40
  • @JBNizet I can't change that now, I need both for different projects – CLOVIS Jul 05 '18 at 11:59
  • That makes no sense. If you have, let's say /JDK8/bin and /JDK10/bin in your path, and you execute `java`, then /JDK8/bin/java will always be executed. So you need to put, in your path, the version ofJava that you want to use. – JB Nizet Jul 05 '18 at 16:11
  • The IDE 'sees' both and I can configure which is used for which project. There's also a 'default-java' symlink that points to the JDK10, that's why it's selected by default. I didn't do that, it's how it's done by APT-GET. – CLOVIS Jul 05 '18 at 17:22
  • The IDE is irrelevant, since you said you used `./gradlew javadoc` to generate your javadoc. The java version that is found in your PATH will be used. – JB Nizet Jul 05 '18 at 18:23

3 Answers3

1

As of Gradle 6.7 you can change the version of Java used for different tasks using Gradle Toolchains for JVM Projects.

So you would define the toolchain in your build.gradle file, pointing it to the version of Java you want to use. This can be a local JDK or if Gradle doesn't detect the local JDK specified, it will download one. You can see what toolchains Gradle detects on your system by running:

gradle -q javaToolchains

In you case you point to Java 8:

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(8)
    }
}

Then point the tasks to it. For the Javadoc task it would be:

tasks.withType(Javadoc) {
    javadocTool.set(javaToolchains.javadocToolFor(java.toolchain))
}

Same thing for the JavaExec and JavaCompile tasks. The setter's are just a bit different:

tasks.withType(JavaExec) {
    javaLauncher.set(javaToolchains.launcherFor(java.toolchain))
}

tasks.withType(JavaCompile) {
    javaCompiler.set(javaToolchains.compilerFor(java.toolchain))
}

That will allow you use different JDK's for different tasks within your main project or even in subprojects (thats how I'm using it)

Side note, the 'java-library' and/or 'application' plugins might be required to get access to the java object in your build.gradle file. I'm not entirely sure since they are already present in the projects I'm using this, someone can comment and clarify.

plugins {
    id 'application'
    id 'java-library'
}
NoThisIsPatrick
  • 134
  • 2
  • 11
0

I changed the version available in the path by doing:

export JAVA_HOME=/usr/lib/jvm/default-java
CLOVIS
  • 771
  • 8
  • 24
0
javadoc {
  options.source = "8"
}

Maybe need to add it to as existing javadoc, javadoc.options, or options block.

It should be a String, not an int. Not sure why the java plugin doesn't automatically set this.