From 9af98745fb2e57fc996593848c9bc0676d3272e0 Mon Sep 17 00:00:00 2001 From: Sam Carlberg Date: Thu, 21 Nov 2024 20:13:26 -0500 Subject: [PATCH 1/3] Add Java module support --- apriltag/build.gradle | 3 ++ apriltag/src/main/java/module-info.java | 14 ++++++ buildSrc/build.gradle | 1 + cameraserver/build.gradle | 1 + cameraserver/src/main/java/module-info.java | 13 ++++++ cscore/build.gradle | 1 + cscore/src/main/java/module-info.java | 11 +++++ .../src/main/java/module-info.java | 13 ++++++ .../src/main/java/module-info.java | 12 +++++ hal/src/main/java/module-info.java | 13 ++++++ ntcore/src/main/java/module-info.java | 9 ++++ romiVendordep/build.gradle | 2 + romiVendordep/src/main/java/module-info.java | 8 ++++ shared/java/javacommon.gradle | 8 ++++ shared/java/javastyle.gradle | 7 +++ shared/java/opencv-module-patches.gradle | 6 +++ shared/java/wpimath-module-patches.gradle | 34 ++++++++++++++ wpilibNewCommands/build.gradle | 2 + .../src/main/java/module-info.java | 14 ++++++ wpilibj/build.gradle | 3 ++ wpilibj/src/main/java/module-info.java | 28 +++++++++++ wpimath/build.gradle | 2 + wpimath/src/main/java/module-info.java | 46 +++++++++++++++++++ wpinet/src/main/java/module-info.java | 9 ++++ wpiunits/src/main/java/module-info.java | 10 ++++ wpiutil/src/main/java/module-info.java | 18 ++++++++ xrpVendordep/build.gradle | 2 + xrpVendordep/src/main/java/module-info.java | 8 ++++ 28 files changed, 298 insertions(+) create mode 100644 apriltag/src/main/java/module-info.java create mode 100644 cameraserver/src/main/java/module-info.java create mode 100644 cscore/src/main/java/module-info.java create mode 100644 epilogue-processor/src/main/java/module-info.java create mode 100644 epilogue-runtime/src/main/java/module-info.java create mode 100644 hal/src/main/java/module-info.java create mode 100644 ntcore/src/main/java/module-info.java create mode 100644 romiVendordep/src/main/java/module-info.java create mode 100644 shared/java/opencv-module-patches.gradle create mode 100644 shared/java/wpimath-module-patches.gradle create mode 100644 wpilibNewCommands/src/main/java/module-info.java create mode 100644 wpilibj/src/main/java/module-info.java create mode 100644 wpimath/src/main/java/module-info.java create mode 100644 wpinet/src/main/java/module-info.java create mode 100644 wpiunits/src/main/java/module-info.java create mode 100644 wpiutil/src/main/java/module-info.java create mode 100644 xrpVendordep/src/main/java/module-info.java diff --git a/apriltag/build.gradle b/apriltag/build.gradle index ffdf094ede0..ad911db169e 100644 --- a/apriltag/build.gradle +++ b/apriltag/build.gradle @@ -48,6 +48,9 @@ dependencies { implementation project(':wpimath') } +apply from: "${rootDir}/shared/java/wpimath-module-patches.gradle" +apply from: "${rootDir}/shared/java/opencv-module-patches.gradle" + sourceSets { main { resources { diff --git a/apriltag/src/main/java/module-info.java b/apriltag/src/main/java/module-info.java new file mode 100644 index 00000000000..888550e017e --- /dev/null +++ b/apriltag/src/main/java/module-info.java @@ -0,0 +1,14 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +module wpilib.apriltag { + requires transitive wpilib.opencv; + requires wpilib.math; + requires wpilib.util; + requires com.fasterxml.jackson.annotation; + requires com.fasterxml.jackson.databind; + + exports edu.wpi.first.apriltag; + exports edu.wpi.first.apriltag.jni; +} diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 99d4892632a..767e2fc905f 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -10,4 +10,5 @@ repositories { } dependencies { implementation "edu.wpi.first:native-utils:2025.3.0" + implementation("org.gradlex:extra-java-module-info:1.9") } diff --git a/cameraserver/build.gradle b/cameraserver/build.gradle index 92925c65646..69a477460e2 100644 --- a/cameraserver/build.gradle +++ b/cameraserver/build.gradle @@ -8,6 +8,7 @@ evaluationDependsOn(':cscore') evaluationDependsOn(':hal') apply from: "${rootDir}/shared/javacpp/setupBuild.gradle" +apply from: "${rootDir}/shared/java/opencv-module-patches.gradle" dependencies { implementation project(':wpiutil') diff --git a/cameraserver/src/main/java/module-info.java b/cameraserver/src/main/java/module-info.java new file mode 100644 index 00000000000..f0ba8940fb9 --- /dev/null +++ b/cameraserver/src/main/java/module-info.java @@ -0,0 +1,13 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +module wpilib.cameraserver { + requires transitive wpilib.opencv; + requires wpilib.cscore; + requires wpilib.ntcore; + requires wpilib.util; + + exports edu.wpi.first.cameraserver; + exports edu.wpi.first.vision; +} diff --git a/cscore/build.gradle b/cscore/build.gradle index 5b2299548d7..db1e962ed92 100644 --- a/cscore/build.gradle +++ b/cscore/build.gradle @@ -14,6 +14,7 @@ if (OperatingSystem.current().isMacOsX()) { } apply from: "${rootDir}/shared/jni/setupBuild.gradle" +apply from: "${rootDir}/shared/java/opencv-module-patches.gradle" model { components { diff --git a/cscore/src/main/java/module-info.java b/cscore/src/main/java/module-info.java new file mode 100644 index 00000000000..b23c3ede20c --- /dev/null +++ b/cscore/src/main/java/module-info.java @@ -0,0 +1,11 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +module wpilib.cscore { + requires wpilib.opencv; + requires wpilib.util; + + exports edu.wpi.first.cscore; + exports edu.wpi.first.cscore.raw; +} diff --git a/epilogue-processor/src/main/java/module-info.java b/epilogue-processor/src/main/java/module-info.java new file mode 100644 index 00000000000..b27e7472e27 --- /dev/null +++ b/epilogue-processor/src/main/java/module-info.java @@ -0,0 +1,13 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +import javax.annotation.processing.Processor; + +module wpilib.epilogue.processor { + requires java.compiler; + requires wpilib.epilogue; + + provides Processor with + edu.wpi.first.epilogue.processor.AnnotationProcessor; +} diff --git a/epilogue-runtime/src/main/java/module-info.java b/epilogue-runtime/src/main/java/module-info.java new file mode 100644 index 00000000000..e3fbd138ff4 --- /dev/null +++ b/epilogue-runtime/src/main/java/module-info.java @@ -0,0 +1,12 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +module wpilib.epilogue { + requires wpilib.ntcore; + requires wpilib.units; + requires wpilib.util; + + exports edu.wpi.first.epilogue; + exports edu.wpi.first.epilogue.logging; +} diff --git a/hal/src/main/java/module-info.java b/hal/src/main/java/module-info.java new file mode 100644 index 00000000000..cb286761de6 --- /dev/null +++ b/hal/src/main/java/module-info.java @@ -0,0 +1,13 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +module wpilib.hal { + requires wpilib.util; + + exports edu.wpi.first.hal; + exports edu.wpi.first.hal.can; + exports edu.wpi.first.hal.communication; + exports edu.wpi.first.hal.simulation; + exports edu.wpi.first.hal.util; +} diff --git a/ntcore/src/main/java/module-info.java b/ntcore/src/main/java/module-info.java new file mode 100644 index 00000000000..48dc1b30046 --- /dev/null +++ b/ntcore/src/main/java/module-info.java @@ -0,0 +1,9 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +module wpilib.ntcore { + requires wpilib.util; + + exports edu.wpi.first.networktables; +} diff --git a/romiVendordep/build.gradle b/romiVendordep/build.gradle index b891c4de406..44b09cb5494 100644 --- a/romiVendordep/build.gradle +++ b/romiVendordep/build.gradle @@ -23,6 +23,8 @@ dependencies { implementation project(":wpilibj") } +apply from: "${rootDir}/shared/java/wpimath-module-patches.gradle" + nativeUtils.exportsConfigs { // Main library is just default empty. This will export everything romiVendordep { diff --git a/romiVendordep/src/main/java/module-info.java b/romiVendordep/src/main/java/module-info.java new file mode 100644 index 00000000000..2bec4799000 --- /dev/null +++ b/romiVendordep/src/main/java/module-info.java @@ -0,0 +1,8 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +module wpilib.romi { + requires transitive wpilib.wpilibj; + requires wpilib.hal; +} diff --git a/shared/java/javacommon.gradle b/shared/java/javacommon.gradle index 7802818b483..5105b2c1e5d 100644 --- a/shared/java/javacommon.gradle +++ b/shared/java/javacommon.gradle @@ -1,6 +1,7 @@ apply plugin: 'maven-publish' apply plugin: 'java-library' apply plugin: 'jacoco' +apply plugin: 'org.gradlex.extra-java-module-info' def baseArtifactId = project.baseId def artifactGroupId = project.groupId @@ -114,6 +115,13 @@ tasks.withType(JavaCompile).configureEach { "-Xlint:-serial", // ignore unclaimed annotation warning from annotation processing "-Xlint:-processing", + "-Xlint:-preview", + // ignore modules requiring automatic library modules + "-Xlint:-requires-automatic", + "-Xlint:-requires-transitive-automatic", + "-Xlint:-exports", + // Java modules warn about exposing classes without an explicitly declared constructor + "-Xlint:-missing-explicit-ctor" ] } diff --git a/shared/java/javastyle.gradle b/shared/java/javastyle.gradle index e2b713e7e6f..33c2b56fa4e 100644 --- a/shared/java/javastyle.gradle +++ b/shared/java/javastyle.gradle @@ -10,6 +10,13 @@ checkstyle { config = resources.text.fromFile(new File(configDirectory.get().getAsFile(), "checkstyle.xml")) } +tasks.withType(Checkstyle) { + // Checkstyle falls over if module-info files are included in the check scope + // The suppressions file does not appear to work for this, so we need to configure the task + // itself + exclude("**/module-info.java") +} + apply plugin: 'pmd' pmd { diff --git a/shared/java/opencv-module-patches.gradle b/shared/java/opencv-module-patches.gradle new file mode 100644 index 00000000000..d34edde8563 --- /dev/null +++ b/shared/java/opencv-module-patches.gradle @@ -0,0 +1,6 @@ +// Patch legacy non-modularized dependencies to have module info +extraJavaModuleInfo { + module('edu.wpi.first.thirdparty.frc2024.opencv:opencv-java', 'wpilib.opencv') { + exportAllPackages() + } +} diff --git a/shared/java/wpimath-module-patches.gradle b/shared/java/wpimath-module-patches.gradle new file mode 100644 index 00000000000..976136370f3 --- /dev/null +++ b/shared/java/wpimath-module-patches.gradle @@ -0,0 +1,34 @@ +// Patch legacy non-modularized dependencies to have module info +extraJavaModuleInfo { + module('org.ejml:ejml-core', 'ejml.core') { + exportAllPackages() + } + module('org.ejml:ejml-simple', 'ejml.simple') { + exportAllPackages() + requiresTransitive('ejml.core') + } + module('org.ejml:ejml-fsparse', 'ejml.fsparse') { + exportAllPackages() + requiresTransitive('ejml.core') + } + module('org.ejml:ejml-dsparse', 'ejml.dsparse') { + exportAllPackages() + requiresTransitive('ejml.core') + } + module('org.ejml:ejml-fdense', 'ejml.fdense') { + exportAllPackages() + requiresTransitive('ejml.core') + } + module('org.ejml:ejml-ddense', 'ejml.ddense') { + exportAllPackages() + requiresTransitive('ejml.core') + } + module('org.ejml:ejml-cdense', 'ejml.cdense') { + exportAllPackages() + requiresTransitive('ejml.core') + } + module('org.ejml:ejml-zdense', 'ejml.zdense') { + exportAllPackages() + requiresTransitive('ejml.core') + } +} diff --git a/wpilibNewCommands/build.gradle b/wpilibNewCommands/build.gradle index 884c18b65cb..55f6027e5ea 100644 --- a/wpilibNewCommands/build.gradle +++ b/wpilibNewCommands/build.gradle @@ -24,6 +24,8 @@ dependencies { testImplementation 'org.mockito:mockito-core:4.1.0' } +apply from: "${rootDir}/shared/java/wpimath-module-patches.gradle" + sourceSets.main.java.srcDir "${projectDir}/src/generated/main/java" nativeUtils.exportsConfigs { diff --git a/wpilibNewCommands/src/main/java/module-info.java b/wpilibNewCommands/src/main/java/module-info.java new file mode 100644 index 00000000000..d6172015fc2 --- /dev/null +++ b/wpilibNewCommands/src/main/java/module-info.java @@ -0,0 +1,14 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +module wpilib.commands2 { + requires wpilib.units; + requires wpilib.wpilibj; + requires wpilib.hal; + requires wpilib.ntcore; + + exports edu.wpi.first.wpilibj2.command; + exports edu.wpi.first.wpilibj2.command.button; + exports edu.wpi.first.wpilibj2.command.sysid; +} diff --git a/wpilibj/build.gradle b/wpilibj/build.gradle index d397f934801..2680ab2dbd6 100644 --- a/wpilibj/build.gradle +++ b/wpilibj/build.gradle @@ -74,6 +74,9 @@ dependencies { devImplementation sourceSets.main.output } +apply from: "${rootDir}/shared/java/opencv-module-patches.gradle" +apply from: "${rootDir}/shared/java/wpimath-module-patches.gradle" + apply plugin: 'cpp' apply plugin: 'edu.wpi.first.NativeUtils' apply plugin: ExtraTasks diff --git a/wpilibj/src/main/java/module-info.java b/wpilibj/src/main/java/module-info.java new file mode 100644 index 00000000000..ef168706e66 --- /dev/null +++ b/wpilibj/src/main/java/module-info.java @@ -0,0 +1,28 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +module wpilib.wpilibj { + requires ejml.core; + requires ejml.simple; + requires transitive wpilib.math; + requires transitive wpilib.units; + requires transitive wpilib.util; + requires wpilib.hal; + requires wpilib.ntcore; + requires wpilib.cscore; + requires wpilib.cameraserver; + + exports edu.wpi.first.wpilibj; + exports edu.wpi.first.wpilibj.counter; + exports edu.wpi.first.wpilibj.drive; + exports edu.wpi.first.wpilibj.event; + exports edu.wpi.first.wpilibj.internal; + exports edu.wpi.first.wpilibj.livewindow; + exports edu.wpi.first.wpilibj.motorcontrol; + exports edu.wpi.first.wpilibj.shuffleboard; + exports edu.wpi.first.wpilibj.simulation; + exports edu.wpi.first.wpilibj.smartdashboard; + exports edu.wpi.first.wpilibj.sysid; + exports edu.wpi.first.wpilibj.util; +} diff --git a/wpimath/build.gradle b/wpimath/build.gradle index 9cb07b416ef..5cad88342e6 100644 --- a/wpimath/build.gradle +++ b/wpimath/build.gradle @@ -90,6 +90,8 @@ dependencies { api "us.hebi.quickbuf:quickbuf-runtime:1.3.3" } +apply from: "${rootDir}/shared/java/wpimath-module-patches.gradle" + sourceSets.main.java.srcDir "${projectDir}/src/generated/main/java" sourceSets.main.resources.srcDir "${projectDir}/src/main/proto" diff --git a/wpimath/src/main/java/module-info.java b/wpimath/src/main/java/module-info.java new file mode 100644 index 00000000000..9e2592bca12 --- /dev/null +++ b/wpimath/src/main/java/module-info.java @@ -0,0 +1,46 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +module wpilib.math { + requires com.fasterxml.jackson.annotation; + requires ejml.core; + requires ejml.ddense; + requires ejml.simple; + requires us.hebi.quickbuf.runtime; + requires wpilib.units; + requires wpilib.util; + + exports edu.wpi.first.math; + exports edu.wpi.first.math.controller; + exports edu.wpi.first.math.controller.proto; + exports edu.wpi.first.math.controller.struct; + exports edu.wpi.first.math.estimator; + exports edu.wpi.first.math.filter; + exports edu.wpi.first.math.geometry; + exports edu.wpi.first.math.geometry.proto; + exports edu.wpi.first.math.geometry.struct; + exports edu.wpi.first.math.interpolation; + exports edu.wpi.first.math.jni; // Probably unnecessary + exports edu.wpi.first.math.kinematics; + exports edu.wpi.first.math.kinematics.proto; + exports edu.wpi.first.math.kinematics.struct; + exports edu.wpi.first.math.optimization; + exports edu.wpi.first.math.path; + exports edu.wpi.first.math.proto; + exports edu.wpi.first.math.spline; + exports edu.wpi.first.math.spline.proto; + exports edu.wpi.first.math.spline.struct; + exports edu.wpi.first.math.struct; + exports edu.wpi.first.math.system; + exports edu.wpi.first.math.system.plant; + exports edu.wpi.first.math.system.plant.proto; + exports edu.wpi.first.math.system.plant.struct; + exports edu.wpi.first.math.system.proto; + exports edu.wpi.first.math.system.struct; + exports edu.wpi.first.math.trajectory; + exports edu.wpi.first.math.trajectory.constraint; + exports edu.wpi.first.math.trajectory.proto; + exports edu.wpi.first.math.util; + exports edu.wpi.first.math.numbers; +} diff --git a/wpinet/src/main/java/module-info.java b/wpinet/src/main/java/module-info.java new file mode 100644 index 00000000000..9487fb3cec1 --- /dev/null +++ b/wpinet/src/main/java/module-info.java @@ -0,0 +1,9 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +module wpilib.net { + requires wpilib.util; + + exports edu.wpi.first.net; +} diff --git a/wpiunits/src/main/java/module-info.java b/wpiunits/src/main/java/module-info.java new file mode 100644 index 00000000000..d8597b04f82 --- /dev/null +++ b/wpiunits/src/main/java/module-info.java @@ -0,0 +1,10 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +module wpilib.units { + exports edu.wpi.first.units; + exports edu.wpi.first.units.collections; + exports edu.wpi.first.units.measure; + exports edu.wpi.first.units.mutable; +} diff --git a/wpiutil/src/main/java/module-info.java b/wpiutil/src/main/java/module-info.java new file mode 100644 index 00000000000..4e402605b6f --- /dev/null +++ b/wpiutil/src/main/java/module-info.java @@ -0,0 +1,18 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +@SuppressWarnings("requires-transitive-automatic") +module wpilib.util { + requires com.fasterxml.jackson.databind; + requires transitive us.hebi.quickbuf.runtime; + + exports edu.wpi.first.util; + exports edu.wpi.first.util.cleanup; + exports edu.wpi.first.util.concurrent; + exports edu.wpi.first.util.datalog; + exports edu.wpi.first.util.function; + exports edu.wpi.first.util.protobuf; + exports edu.wpi.first.util.sendable; + exports edu.wpi.first.util.struct; +} diff --git a/xrpVendordep/build.gradle b/xrpVendordep/build.gradle index 21278f55dee..1649cbc21e2 100644 --- a/xrpVendordep/build.gradle +++ b/xrpVendordep/build.gradle @@ -23,6 +23,8 @@ dependencies { implementation project(":wpilibj") } +apply from: "${rootDir}/shared/java/wpimath-module-patches.gradle" + nativeUtils.exportsConfigs { // Main library is just default empty. This will export everything xrpVendordep { diff --git a/xrpVendordep/src/main/java/module-info.java b/xrpVendordep/src/main/java/module-info.java new file mode 100644 index 00000000000..e6238e84262 --- /dev/null +++ b/xrpVendordep/src/main/java/module-info.java @@ -0,0 +1,8 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +module wpilib.xrp { + requires transitive wpilib.wpilibj; + requires wpilib.hal; +} From f47421a45fd22d2349fec344d5356f89efad70c9 Mon Sep 17 00:00:00 2001 From: Sam Carlberg Date: Thu, 21 Nov 2024 21:57:29 -0500 Subject: [PATCH 2/3] Suppress module name warnings --- shared/java/javacommon.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/shared/java/javacommon.gradle b/shared/java/javacommon.gradle index 5105b2c1e5d..fc17c7ebfa5 100644 --- a/shared/java/javacommon.gradle +++ b/shared/java/javacommon.gradle @@ -121,7 +121,9 @@ tasks.withType(JavaCompile).configureEach { "-Xlint:-requires-transitive-automatic", "-Xlint:-exports", // Java modules warn about exposing classes without an explicitly declared constructor - "-Xlint:-missing-explicit-ctor" + "-Xlint:-missing-explicit-ctor", + // Java modules warn about module names with trailing digits + "-Xlint:-module" ] } From bb536c27c5f30ce6204cb31611ab3435cee86a87 Mon Sep 17 00:00:00 2001 From: Sam Carlberg Date: Thu, 21 Nov 2024 21:57:46 -0500 Subject: [PATCH 3/3] Add jdk.compiler to requirements for epilogue-processor --- epilogue-processor/src/main/java/module-info.java | 1 + 1 file changed, 1 insertion(+) diff --git a/epilogue-processor/src/main/java/module-info.java b/epilogue-processor/src/main/java/module-info.java index b27e7472e27..7cb7a7fbf70 100644 --- a/epilogue-processor/src/main/java/module-info.java +++ b/epilogue-processor/src/main/java/module-info.java @@ -6,6 +6,7 @@ module wpilib.epilogue.processor { requires java.compiler; + requires jdk.compiler; requires wpilib.epilogue; provides Processor with