diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 7701eabf0b..9d0ad90439 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -45,13 +45,13 @@ jobs: uses: gradle/gradle-build-action@v2 with: gradle-executable: xvfb-gradle.sh - arguments: aggregatedJavadocs build publishAllPublicationsToFakeRemoteRepository shellcheck --no-configuration-cache + arguments: aggregatedJavadocs build publishAllPublicationsToFakeRemoteRepository shellcheck --no-configuration-cache -Pcom.ibm.wala.jdk-version=${{ matrix.java }} # testing ECJ compilation on any one OS is sufficient; we choose Linux arbitrarily if: runner.os == 'Linux' - name: Build and test using Gradle but without ECJ uses: gradle/gradle-build-action@v2 with: - arguments: aggregatedJavadocs javadoc build -PskipJavaUsingEcjTasks --no-configuration-cache + arguments: aggregatedJavadocs javadoc build -PskipJavaUsingEcjTasks --no-configuration-cache -Pcom.ibm.wala.jdk-version=${{ matrix.java }} if: runner.os != 'Linux' - name: Check for Git cleanliness after build and test run: ./check-git-cleanliness.sh diff --git a/build-logic/src/main/kotlin/com/ibm/wala/gradle/EclipseCompatibleJavaExtension.kt b/build-logic/src/main/kotlin/com/ibm/wala/gradle/EclipseCompatibleJavaExtension.kt new file mode 100644 index 0000000000..c953ef4fa5 --- /dev/null +++ b/build-logic/src/main/kotlin/com/ibm/wala/gradle/EclipseCompatibleJavaExtension.kt @@ -0,0 +1,45 @@ +package com.ibm.wala.gradle + +import javax.inject.Inject +import org.gradle.api.Project +import org.gradle.api.plugins.JavaPluginExtension +import org.gradle.api.provider.Provider +import org.gradle.jvm.toolchain.JavaLanguageVersion +import org.gradle.jvm.toolchain.JavaLauncher +import org.gradle.jvm.toolchain.JavaToolchainService +import org.gradle.kotlin.dsl.the + +/** + * The earliest Java version that is compatible with bytecode used in Eclipse dependencies. + * + * When changing `eclipse` in the `versions` section of `gradle/libs.versions.toml`, consider + * whether this value needs to be changed as well. + */ +private const val MINIMUM_ECLIPSE_COMPATIBLE_JAVA_VERSION = 17 + +/** + * A Gradle [Project] extension providing details about to Eclipse-compatible Java toolchains. + * + * @constructor Creates an extension instance that will be attached to the given [project]. + * @property project The project to which this extension instance is attached. + * @property languageVersion A Java language version that is compatible with WALA's Eclipse + * dependencies. + * @property launcher Provides a Java JVM launcher (i.e., `java` command) that is compatible with + * WALA's Eclipse dependencies. + */ +open class EclipseCompatibleJavaExtension @Inject constructor(private val project: Project) { + + val languageVersion: JavaLanguageVersion by lazy { + project.run { + val projectVersion = the().toolchain.languageVersion.get() + val minimumVersion = JavaLanguageVersion.of(MINIMUM_ECLIPSE_COMPATIBLE_JAVA_VERSION) + if (projectVersion.canCompileOrRun(minimumVersion)) projectVersion else minimumVersion + } + } + + val launcher: Provider by lazy { + project.the().launcherFor { + languageVersion.set(this@EclipseCompatibleJavaExtension.languageVersion) + } + } +} diff --git a/build-logic/src/main/kotlin/com/ibm/wala/gradle/JavaCompileUsingEcj.kt b/build-logic/src/main/kotlin/com/ibm/wala/gradle/JavaCompileUsingEcj.kt index ba3080b420..65e4e49a68 100644 --- a/build-logic/src/main/kotlin/com/ibm/wala/gradle/JavaCompileUsingEcj.kt +++ b/build-logic/src/main/kotlin/com/ibm/wala/gradle/JavaCompileUsingEcj.kt @@ -4,6 +4,7 @@ import java.io.File import javax.inject.Inject import org.gradle.api.Project import org.gradle.api.file.RegularFile +import org.gradle.api.provider.Provider import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.CompileClasspath import org.gradle.api.tasks.InputFile @@ -14,6 +15,7 @@ import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.compile.JavaCompile import org.gradle.kotlin.dsl.named +import org.gradle.kotlin.dsl.the import org.gradle.process.ExecOperations /** @@ -35,6 +37,16 @@ abstract class JavaCompileUsingEcj : JavaCompile() { @get:Inject abstract val execOperations: ExecOperations + /** + * The path to the Java launcher executable used for running the Eclipse Java compiler (ECJ). + * + * @see EclipseCompatibleJavaExtension.launcher + */ + @InputFile + @PathSensitive(PathSensitivity.NONE) + val javaLauncherPath: Provider = + project.the().launcher.map { it.executablePath } + init { options.compilerArgumentProviders.run { add { @@ -54,6 +66,7 @@ abstract class JavaCompileUsingEcj : JavaCompile() { fun compile() { execOperations.javaexec { classpath(ecjJar.absolutePath) + executable(javaLauncherPath.get()) args(options.allCompilerArgs) } } diff --git a/build-logic/src/main/kotlin/com/ibm/wala/gradle/eclipse-compatible-java.gradle.kts b/build-logic/src/main/kotlin/com/ibm/wala/gradle/eclipse-compatible-java.gradle.kts new file mode 100644 index 0000000000..73d21f3638 --- /dev/null +++ b/build-logic/src/main/kotlin/com/ibm/wala/gradle/eclipse-compatible-java.gradle.kts @@ -0,0 +1,6 @@ +package com.ibm.wala.gradle + +plugins { java } + +// Make Eclipse-compatible Java information available as `project.eclipseCompatibleJava`. +extensions.create("eclipseCompatibleJava") diff --git a/build-logic/src/main/kotlin/com/ibm/wala/gradle/eclipse-maven-central.gradle.kts b/build-logic/src/main/kotlin/com/ibm/wala/gradle/eclipse-maven-central.gradle.kts index 1b1be66d98..22430860dc 100644 --- a/build-logic/src/main/kotlin/com/ibm/wala/gradle/eclipse-maven-central.gradle.kts +++ b/build-logic/src/main/kotlin/com/ibm/wala/gradle/eclipse-maven-central.gradle.kts @@ -4,7 +4,16 @@ import com.diffplug.gradle.eclipse.MavenCentralExtension.ReleaseConfigurer import com.diffplug.gradle.eclipse.MavenCentralPlugin import com.diffplug.gradle.pde.EclipseRelease -plugins { id("com.diffplug.eclipse.mavencentral") } +plugins { + id("com.diffplug.eclipse.mavencentral") + id("com.ibm.wala.gradle.eclipse-compatible-java") + id("com.ibm.wala.gradle.java") +} + +// This subproject uses one or more Eclipse dependencies. Eensure that it is using an +// Eclipse-compatible Java toolchain. That toolchain might be newer than the Java toolchain that +// WALA uses elsewhere. +java.toolchain.languageVersion = the().languageVersion /** * WALA-specialized adaptation of diff --git a/build-logic/src/main/kotlin/com/ibm/wala/gradle/java.gradle.kts b/build-logic/src/main/kotlin/com/ibm/wala/gradle/java.gradle.kts index f0456d590c..d7d81f0eec 100644 --- a/build-logic/src/main/kotlin/com/ibm/wala/gradle/java.gradle.kts +++ b/build-logic/src/main/kotlin/com/ibm/wala/gradle/java.gradle.kts @@ -13,6 +13,7 @@ plugins { `maven-publish` signing id("com.diffplug.spotless") + id("com.ibm.wala.gradle.eclipse-compatible-java") id("com.ibm.wala.gradle.javadoc") id("com.ibm.wala.gradle.subproject") id("net.ltgt.errorprone") @@ -24,6 +25,9 @@ repositories { maven { url = uri("https://storage.googleapis.com/r8-releases/raw") } } +java.toolchain.languageVersion = + JavaLanguageVersion.of(property("com.ibm.wala.jdk-version") as String) + base.archivesName = "com.ibm.wala${project.path.replace(':', '.')}" configurations { diff --git a/cast/java/test/data/.settings/org.eclipse.jdt.core.prefs b/cast/java/test/data/.settings/org.eclipse.jdt.core.prefs index cf946c8de5..6075f94144 100644 --- a/cast/java/test/data/.settings/org.eclipse.jdt.core.prefs +++ b/cast/java/test/data/.settings/org.eclipse.jdt.core.prefs @@ -91,7 +91,7 @@ org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=enabled org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.terminalDeprecation=error +org.eclipse.jdt.core.compiler.problem.terminalDeprecation=ignore org.eclipse.jdt.core.compiler.problem.typeParameterHiding=error org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore diff --git a/gradle.properties b/gradle.properties index 58278a230d..d90e9f6093 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,8 @@ +# Preferred JDK version to use for compiling WALA and running WALA tests. WALA's Eclipse-dependent +# components may override this with something newer; see `MINIMUM_ECLIPSE_COMPATIBLE_JAVA_VERSION` +# in `build-logic/src/main/kotlin/com/ibm/wala/gradle/EclipseCompatibleJavaExtension.kt`. +com.ibm.wala.jdk-version=11 + org.gradle.caching=true org.gradle.configuration-cache=true org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5766673be4..f75038ed82 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -eclipse = "4.21.0" +eclipse = "4.30.0" eclipse-wst-jsdt = "1.0.201.v2010012803" google-java-format = "1.17.0" ktfmt = "0.44" diff --git a/settings.gradle.kts b/settings.gradle.kts index 65c52f5c21..ad4b46b0a4 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,9 @@ buildscript { dependencies { classpath("com.diffplug.spotless:spotless-lib-extra:2.43.1") } } -plugins { id("com.diffplug.configuration-cache-for-platform-specific-build") version "3.44.0" } +plugins { + id("com.diffplug.configuration-cache-for-platform-specific-build") version "3.44.0" + id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" +} enableFeaturePreview("STABLE_CONFIGURATION_CACHE")