diff --git a/BUILD.bazel b/BUILD.bazel index bcbb962eae..cdb0bba649 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1,10 +1,20 @@ load("@aspect_bazel_lib//lib:write_source_files.bzl", "write_source_files") load("@rules_java//java:java_binary.bzl", "java_binary") +load("@rules_java//java:java_plugin.bzl", "java_plugin") load("@rules_pkg//:mappings.bzl", "pkg_files") load("@rules_python//python:pip.bzl", "compile_pip_requirements") load("//shared/bazel/rules:publishing.bzl", "publish_all") load("//shared/bazel/rules/robotpy:compatibility_select.bzl", "robotpy_compatibility_select") +java_plugin( + name = "avaje_jsonb_generator", + processor_class = "io.avaje.jsonb.generator.JsonbProcessor", + visibility = ["//visibility:public"], + deps = [ + "@maven//:io_avaje_avaje_jsonb_generator", + ], +) + exports_files([ "LICENSE.md", "ThirdPartyNotices.txt", diff --git a/CMakeLists.txt b/CMakeLists.txt index 2943dc85ef..bd75892648 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,7 +131,7 @@ wpilib_config(OPTIONS WITH_WPIMATH WITH_JAVA REQUIRES WITH_WPIUNITS) set(include_dest include) set(java_lib_dest java) if(WITH_JAVA OR WITH_JAVA_SOURCE) - set(CMAKE_JAVA_COMPILE_FLAGS "-encoding" "UTF8" "-Xlint:unchecked") + set(CMAKE_JAVA_COMPILE_FLAGS "-encoding" "UTF8" "-Xlint:unchecked" "-proc:full") find_package(Java REQUIRED COMPONENTS Development) if(NOT ANDROID) find_package(JNI REQUIRED COMPONENTS JVM) diff --git a/MODULE.bazel b/MODULE.bazel index de28107f88..5e46a6bf80 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -51,9 +51,8 @@ maven.install( name = "maven", artifacts = [ "org.ejml:ejml-simple:0.44.0", - "com.fasterxml.jackson.core:jackson-annotations:2.19.2", - "com.fasterxml.jackson.core:jackson-core:2.19.2", - "com.fasterxml.jackson.core:jackson-databind:2.19.2", + "io.avaje:avaje-jsonb:3.11", + "io.avaje:avaje-jsonb-generator:3.11", "us.hebi.quickbuf:quickbuf-runtime:1.4", "com.google.code.gson:gson:2.13.1", "edu.wpi.first.thirdparty.frc2025.opencv:opencv-java:4.10.0-3", diff --git a/apriltag/BUILD.bazel b/apriltag/BUILD.bazel index 9fc0ed5d78..de9fd85f2b 100644 --- a/apriltag/BUILD.bazel +++ b/apriltag/BUILD.bazel @@ -140,6 +140,9 @@ wpilib_jni_java_library( maven_artifact_name = "apriltag-java", maven_group_id = "org.wpilib.apriltag", native_libs = [":apriltagjni"], + plugins = [ + "//:avaje_jsonb_generator", + ], resource_strip_prefix = "apriltag/src/main/native/resources", resources = glob(["src/main/native/resources/**"]), visibility = ["//visibility:public"], @@ -147,9 +150,8 @@ wpilib_jni_java_library( "//wpimath:wpimath-java", "//wpiutil:wpiutil-java", "@bzlmodrio-opencv//libraries/java/opencv", - "@maven//:com_fasterxml_jackson_core_jackson_annotations", - "@maven//:com_fasterxml_jackson_core_jackson_core", - "@maven//:com_fasterxml_jackson_core_jackson_databind", + "@maven//:io_avaje_avaje_json_core", + "@maven//:io_avaje_avaje_jsonb", ], ) @@ -182,7 +184,7 @@ wpilib_java_junit5_test( "//wpimath:wpimath-java", "//wpiutil:wpiutil-java", "@bzlmodrio-opencv//libraries/java/opencv", - "@maven//:com_fasterxml_jackson_core_jackson_databind", + "@maven//:io_avaje_avaje_jsonb", ], ) diff --git a/apriltag/CMakeLists.txt b/apriltag/CMakeLists.txt index 223d055bb1..9d1606d737 100644 --- a/apriltag/CMakeLists.txt +++ b/apriltag/CMakeLists.txt @@ -39,7 +39,7 @@ if(WITH_JAVA) set(CMAKE_JNI_TARGET true) file(GLOB EJML_JARS "${WPILIB_BINARY_DIR}/wpimath/thirdparty/ejml/*.jar") - file(GLOB JACKSON_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/jackson/*.jar") + file(GLOB AVAJE_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/avaje/*.jar") find_file( OPENCV_JAR_FILE NAMES opencv-${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}.jar @@ -69,7 +69,7 @@ if(WITH_JAVA) wpiutil_jar ${EJML_JARS} ${OPENCV_JAR_FILE} - ${JACKSON_JARS} + ${AVAJE_JARS} OUTPUT_NAME apriltag OUTPUT_DIR ${WPILIB_BINARY_DIR}/${java_lib_dest} GENERATE_NATIVE_HEADERS apriltag_jni_headers diff --git a/apriltag/build.gradle b/apriltag/build.gradle index 909bf1df74..14daba3bee 100644 --- a/apriltag/build.gradle +++ b/apriltag/build.gradle @@ -46,6 +46,7 @@ apply from: "${rootDir}/shared/opencv.gradle" dependencies { implementation project(':wpimath') + annotationProcessor libs.avaje.jsonb.generator } sourceSets { diff --git a/apriltag/src/main/java/org/wpilib/vision/apriltag/AprilTag.java b/apriltag/src/main/java/org/wpilib/vision/apriltag/AprilTag.java index 05f8fab181..b2f36c1d0c 100644 --- a/apriltag/src/main/java/org/wpilib/vision/apriltag/AprilTag.java +++ b/apriltag/src/main/java/org/wpilib/vision/apriltag/AprilTag.java @@ -4,8 +4,7 @@ package org.wpilib.vision.apriltag; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; +import io.avaje.jsonb.Json; import java.util.Objects; import org.wpilib.math.geometry.Pose3d; import org.wpilib.util.RawFrame; @@ -13,13 +12,14 @@ import org.wpilib.vision.apriltag.jni.AprilTagJNI; /** Represents an AprilTag's metadata. */ @SuppressWarnings("MemberName") +@Json public class AprilTag { /** The tag's ID. */ - @JsonProperty(value = "ID") + @Json.Property("ID") public int ID; /** The tag's pose. */ - @JsonProperty(value = "pose") + @Json.Property("pose") public Pose3d pose; /** @@ -29,10 +29,8 @@ public class AprilTag { * @param pose The tag's pose. */ @SuppressWarnings("ParameterName") - @JsonCreator - public AprilTag( - @JsonProperty(required = true, value = "ID") int ID, - @JsonProperty(required = true, value = "pose") Pose3d pose) { + @Json.Creator + public AprilTag(int ID, Pose3d pose) { this.ID = ID; this.pose = pose; } diff --git a/apriltag/src/main/java/org/wpilib/vision/apriltag/AprilTagFieldLayout.java b/apriltag/src/main/java/org/wpilib/vision/apriltag/AprilTagFieldLayout.java index 263af46379..62b878ed9b 100644 --- a/apriltag/src/main/java/org/wpilib/vision/apriltag/AprilTagFieldLayout.java +++ b/apriltag/src/main/java/org/wpilib/vision/apriltag/AprilTagFieldLayout.java @@ -4,17 +4,12 @@ package org.wpilib.vision.apriltag; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; +import io.avaje.jsonb.Json; +import io.avaje.jsonb.Jsonb; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.UncheckedIOException; -import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.HashMap; @@ -43,8 +38,7 @@ import org.wpilib.math.geometry.Translation3d; *

Tag poses represent the center of the tag, with a zero rotation representing a tag that is * upright and facing away from the (blue) alliance wall (that is, towards the opposing alliance). */ -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE) +@Json public class AprilTagFieldLayout { /** Common origin positions for the AprilTag coordinate system. */ public enum OriginPosition { @@ -54,12 +48,12 @@ public class AprilTagFieldLayout { kRedAllianceWallRightSide, } - private final Map m_apriltags = new HashMap<>(); + @Json.Ignore private final Map m_apriltags = new HashMap<>(); - @JsonProperty(value = "field") - private FieldDimensions m_fieldDimensions; + @Json.Property("field") + FieldDimensions m_fieldDimensions; - private Pose3d m_origin; + @Json.Ignore private Pose3d m_origin; /** * Construct a new AprilTagFieldLayout with values imported from a JSON file. @@ -79,7 +73,7 @@ public class AprilTagFieldLayout { */ public AprilTagFieldLayout(Path path) throws IOException { AprilTagFieldLayout layout = - new ObjectMapper().readValue(path.toFile(), AprilTagFieldLayout.class); + Jsonb.instance().type(AprilTagFieldLayout.class).fromJson(Files.newBufferedReader(path)); m_apriltags.putAll(layout.m_apriltags); m_fieldDimensions = layout.m_fieldDimensions; setOrigin(OriginPosition.kBlueAllianceWallRightSide); @@ -96,10 +90,10 @@ public class AprilTagFieldLayout { this(apriltags, new FieldDimensions(fieldLength, fieldWidth)); } - @JsonCreator - private AprilTagFieldLayout( - @JsonProperty(required = true, value = "tags") List apriltags, - @JsonProperty(required = true, value = "field") FieldDimensions fieldDimensions) { + @Json.Creator + AprilTagFieldLayout( + @Json.Alias("tags") List apriltags, + @Json.Alias("field") FieldDimensions fieldDimensions) { // To ensure the underlying semantics don't change with what kind of list is passed in for (AprilTag tag : apriltags) { m_apriltags.put(tag.ID, tag); @@ -113,7 +107,7 @@ public class AprilTagFieldLayout { * * @return The {@link AprilTag AprilTags} used in this layout. */ - @JsonProperty("tags") + @Json.Property("tags") public List getTags() { return new ArrayList<>(m_apriltags.values()); } @@ -123,7 +117,6 @@ public class AprilTagFieldLayout { * * @return length, in meters */ - @JsonIgnore public double getFieldLength() { return m_fieldDimensions.fieldLength; } @@ -133,7 +126,6 @@ public class AprilTagFieldLayout { * * @return width, in meters */ - @JsonIgnore public double getFieldWidth() { return m_fieldDimensions.fieldWidth; } @@ -147,7 +139,6 @@ public class AprilTagFieldLayout { * * @param origin The predefined origin */ - @JsonIgnore public final void setOrigin(OriginPosition origin) { var pose = switch (origin) { @@ -168,7 +159,6 @@ public class AprilTagFieldLayout { * * @param origin The new origin for tag transformations */ - @JsonIgnore public final void setOrigin(Pose3d origin) { m_origin = origin; } @@ -178,7 +168,6 @@ public class AprilTagFieldLayout { * * @return the origin */ - @JsonIgnore public Pose3d getOrigin() { return m_origin; } @@ -216,7 +205,7 @@ public class AprilTagFieldLayout { * @throws IOException If writing to the file fails. */ public void serialize(Path path) throws IOException { - new ObjectMapper().writeValue(path.toFile(), this); + Jsonb.instance().type(AprilTagFieldLayout.class).toJson(this, Files.newBufferedWriter(path)); } /** @@ -253,16 +242,12 @@ public class AprilTagFieldLayout { * @throws IOException If the resource could not be loaded */ public static AprilTagFieldLayout loadFromResource(String resourcePath) throws IOException { - InputStream stream = AprilTagFieldLayout.class.getResourceAsStream(resourcePath); - if (stream == null) { - // Class.getResourceAsStream() returns null if the resource does not exist. - throw new IOException("Could not locate resource: " + resourcePath); - } - InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8); - try { - return new ObjectMapper().readerFor(AprilTagFieldLayout.class).readValue(reader); - } catch (IOException e) { - throw new IOException("Failed to load AprilTagFieldLayout: " + resourcePath); + try (InputStream stream = AprilTagFieldLayout.class.getResourceAsStream(resourcePath)) { + if (stream == null) { + // Class.getResourceAsStream() returns null if the resource does not exist. + throw new IOException("Could not locate resource: " + resourcePath); + } + return Jsonb.instance().type(AprilTagFieldLayout.class).fromJson(stream); } } @@ -278,21 +263,19 @@ public class AprilTagFieldLayout { return Objects.hash(m_apriltags, m_origin); } - @JsonIgnoreProperties(ignoreUnknown = true) - @JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE) - private static class FieldDimensions { + static class FieldDimensions { @SuppressWarnings("MemberName") - @JsonProperty(value = "length") + @Json.Property(value = "length") public final double fieldLength; @SuppressWarnings("MemberName") - @JsonProperty(value = "width") + @Json.Property(value = "width") public final double fieldWidth; - @JsonCreator() + @Json.Creator() FieldDimensions( - @JsonProperty(required = true, value = "length") double fieldLength, - @JsonProperty(required = true, value = "width") double fieldWidth) { + @Json.Alias(value = "length") double fieldLength, + @Json.Alias(value = "width") double fieldWidth) { this.fieldLength = fieldLength; this.fieldWidth = fieldWidth; } diff --git a/apriltag/src/test/java/org/wpilib/vision/apriltag/AprilTagSerializationTest.java b/apriltag/src/test/java/org/wpilib/vision/apriltag/AprilTagSerializationTest.java index 8773f90bb2..1b3aee8435 100644 --- a/apriltag/src/test/java/org/wpilib/vision/apriltag/AprilTagSerializationTest.java +++ b/apriltag/src/test/java/org/wpilib/vision/apriltag/AprilTagSerializationTest.java @@ -7,7 +7,7 @@ package org.wpilib.vision.apriltag; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; -import com.fasterxml.jackson.databind.ObjectMapper; +import io.avaje.jsonb.Jsonb; import java.util.List; import org.junit.jupiter.api.Test; import org.wpilib.math.geometry.Pose3d; @@ -25,13 +25,9 @@ class AprilTagSerializationTest { Units.feetToMeters(54.0), Units.feetToMeters(27.0)); - var objectMapper = new ObjectMapper(); + var layoutType = Jsonb.instance().type(AprilTagFieldLayout.class); - var deserialized = - assertDoesNotThrow( - () -> - objectMapper.readValue( - objectMapper.writeValueAsString(layout), AprilTagFieldLayout.class)); + var deserialized = assertDoesNotThrow(() -> layoutType.fromJson(layoutType.toJson(layout))); assertEquals(layout, deserialized); } diff --git a/benchmark/build.gradle b/benchmark/build.gradle index 22ef4e1baf..974cb0753b 100644 --- a/benchmark/build.gradle +++ b/benchmark/build.gradle @@ -37,6 +37,11 @@ application { apply plugin: 'com.gradleup.shadow' +shadowJar { + mergeServiceFiles() + duplicatesStrategy = DuplicatesStrategy.INCLUDE +} + repositories { maven { url = 'https://frcmaven.wpi.edu/artifactory/ex-mvn' diff --git a/commandsv2/CMakeLists.txt b/commandsv2/CMakeLists.txt index 414e0b4af2..d38f48264f 100644 --- a/commandsv2/CMakeLists.txt +++ b/commandsv2/CMakeLists.txt @@ -8,14 +8,14 @@ if(WITH_JAVA) include(UseJava) file(GLOB_RECURSE JAVA_SOURCES src/main/java/*.java src/generated/main/java/*.java) - file(GLOB JACKSON_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/jackson/*.jar") + file(GLOB AVAJE_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/avaje/*.jar") add_jar( commandsv2_jar ${JAVA_SOURCES} INCLUDE_JARS hal_jar ntcore_jar - ${JACKSON_JARS} + ${AVAJE_JARS} cscore_jar cameraserver_jar wpimath_jar diff --git a/fields/BUILD.bazel b/fields/BUILD.bazel index b349ba481a..2661cb906c 100644 --- a/fields/BUILD.bazel +++ b/fields/BUILD.bazel @@ -38,12 +38,15 @@ wpilib_java_library( extra_source_pkgs = ["resources"], maven_artifact_name = "fields-java", maven_group_id = "org.wpilib.fields", + plugins = [ + "//:avaje_jsonb_generator", + ], resource_strip_prefix = "fields/src/main/native/resources", resources = glob(["src/main/native/resources/**"]), visibility = ["//visibility:public"], deps = [ - "@maven//:com_fasterxml_jackson_core_jackson_annotations", - "@maven//:com_fasterxml_jackson_core_jackson_databind", + "@maven//:io_avaje_avaje_json_core", + "@maven//:io_avaje_avaje_jsonb", ], ) diff --git a/fields/CMakeLists.txt b/fields/CMakeLists.txt index 7ecf62e5ac..fdcc22a896 100644 --- a/fields/CMakeLists.txt +++ b/fields/CMakeLists.txt @@ -6,7 +6,7 @@ include(GenResources) if(WITH_JAVA) include(UseJava) - file(GLOB JACKSON_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/jackson/*.jar") + file(GLOB AVAJE_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/avaje/*.jar") file(GLOB_RECURSE JAVA_SOURCES src/main/java/*.java) file( @@ -21,7 +21,7 @@ if(WITH_JAVA) SOURCES ${JAVA_SOURCES} RESOURCES NAMESPACE "org/wpilib/fields" ${JAVA_RESOURCES} - INCLUDE_JARS ${JACKSON_JARS} + INCLUDE_JARS ${AVAJE_JARS} OUTPUT_DIR ${WPILIB_BINARY_DIR}/${java_lib_dest} OUTPUT_NAME fields ) diff --git a/fields/build.gradle b/fields/build.gradle index ed72c1f8d3..7237d6c21a 100644 --- a/fields/build.gradle +++ b/fields/build.gradle @@ -14,7 +14,8 @@ if (OperatingSystem.current().isWindows()) { } dependencies { - implementation libs.bundles.jackson + annotationProcessor libs.avaje.jsonb.generator + implementation libs.avaje.jsonb } ext { diff --git a/fields/src/main/java/org/wpilib/fields/FieldConfig.java b/fields/src/main/java/org/wpilib/fields/FieldConfig.java index cd1a29cbd9..2b604697f1 100644 --- a/fields/src/main/java/org/wpilib/fields/FieldConfig.java +++ b/fields/src/main/java/org/wpilib/fields/FieldConfig.java @@ -4,39 +4,38 @@ package org.wpilib.fields; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; +import io.avaje.jsonb.Json; +import io.avaje.jsonb.Jsonb; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.net.URL; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +@Json public class FieldConfig { public static class Corners { - @JsonProperty("top-left") + @Json.Property("top-left") public double[] m_topLeft; - @JsonProperty("bottom-right") + @Json.Property("bottom-right") public double[] m_bottomRight; } - @JsonProperty("game") + @Json.Property("game") public String m_game; - @JsonProperty("field-image") + @Json.Property("field-image") public String m_fieldImage; - @JsonProperty("field-corners") + @Json.Property("field-corners") public Corners m_fieldCorners; - @JsonProperty("field-size") + @Json.Property("field-size") public double[] m_fieldSize; - @JsonProperty("field-unit") + @Json.Property("field-unit") public String m_fieldUnit; public FieldConfig() {} @@ -69,7 +68,7 @@ public class FieldConfig { */ public static FieldConfig loadFromFile(Path file) throws IOException { try (BufferedReader reader = Files.newBufferedReader(file)) { - return new ObjectMapper().readerFor(FieldConfig.class).readValue(reader); + return Jsonb.instance().type(FieldConfig.class).fromJson(reader); } } @@ -81,9 +80,8 @@ public class FieldConfig { * @throws IOException Throws if the resource could not be loaded */ public static FieldConfig loadFromResource(String resourcePath) throws IOException { - try (InputStream stream = FieldConfig.class.getResourceAsStream(resourcePath); - InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8)) { - return new ObjectMapper().readerFor(FieldConfig.class).readValue(reader); + try (InputStream stream = FieldConfig.class.getResourceAsStream(resourcePath)) { + return Jsonb.instance().type(FieldConfig.class).fromJson(stream); } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7498fa3e6b..4065d8d7ed 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] +avaje = "3.11" ejml = "0.44.0" -jackson = "2.19.2" jmh = "1.37" opencv = "4.10.0-3" thirdparty-year = "frc2025" # Note: this also appears in the opencv module name in the libraries section @@ -8,11 +8,10 @@ quickbuf = "1.4" [libraries] # General runtime dependencies +avaje-jsonb = { module = "io.avaje:avaje-jsonb", version.ref = "avaje" } +avaje-jsonb-generator = { module = "io.avaje:avaje-jsonb-generator", version.ref = "avaje" } ejml-simple = { module = "org.ejml:ejml-simple", version.ref = "ejml" } # also pulls in other EJML modules as transitive dependencies gson = { module = "com.google.code.gson:gson", version = "2.13.1" } -jackson-annotations = { module = "com.fasterxml.jackson.core:jackson-annotations", version.ref = "jackson" } -jackson-core = { module = "com.fasterxml.jackson.core:jackson-core", version.ref = "jackson" } -jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } quickbuf-runtime = { module = "us.hebi.quickbuf:quickbuf-runtime", version.ref = "quickbuf" } thirdparty-opencv = { module = "edu.wpi.first.thirdparty.frc2025.opencv:opencv-java", version.ref = "opencv" } @@ -32,7 +31,6 @@ wpilib-native-utils = { module = "org.wpilib:native-utils", version = "2027.5.1" [bundles] ejml = ["ejml-simple"] -jackson = ["jackson-annotations", "jackson-core", "jackson-databind"] mockito = ["mockito-core"] # junit api and launcher artifacts are different dependency types (implementation and runtime, respectively), # so it doesn't make sense to bundle them in a single "junit" bundle diff --git a/maven_install.json b/maven_install.json index c3ea00b51c..805aeafc94 100755 --- a/maven_install.json +++ b/maven_install.json @@ -1,29 +1,11 @@ { "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": -473291874, - "__RESOLVED_ARTIFACTS_HASH": -2131718891, + "__INPUT_ARTIFACTS_HASH": -1041456735, + "__RESOLVED_ARTIFACTS_HASH": 1647610835, "conflict_resolution": { "com.google.errorprone:error_prone_annotations:2.5.1": "com.google.errorprone:error_prone_annotations:2.38.0" }, "artifacts": { - "com.fasterxml.jackson.core:jackson-annotations": { - "shasums": { - "jar": "e516743a316dcf83c572ffc9cb6e8c5e8c134880c8c5155b02f7b34e9c5dc3cf" - }, - "version": "2.19.2" - }, - "com.fasterxml.jackson.core:jackson-core": { - "shasums": { - "jar": "aa77eaf29293a868c47372194f7c5287d77d9370b04ea25d3fffc1e4904b5880" - }, - "version": "2.19.2" - }, - "com.fasterxml.jackson.core:jackson-databind": { - "shasums": { - "jar": "0a1bd4e9b0d670e632d40ee8c625ad376233502f03c2f5889baea95d025b47a7" - }, - "version": "2.19.2" - }, "com.google.auto.value:auto-value": { "shasums": { "jar": "7ca3edd75517fcc8bfc420fda15d2ae2e89ebd6ed477b351caa746e44b2d5603" @@ -114,6 +96,42 @@ }, "version": "4.10.0-3" }, + "io.avaje:avaje-json-core": { + "shasums": { + "jar": "9a784937ea8fe888effa0056a0acc48d07b0cad6fbe5a1e6a72f3928545aab61" + }, + "version": "3.11" + }, + "io.avaje:avaje-jsonb": { + "shasums": { + "jar": "65a575f5eaa0cecf262de37ca91e0129d7857135f2d2d9b2e1e2dbdc502a95ce" + }, + "version": "3.11" + }, + "io.avaje:avaje-jsonb-generator": { + "shasums": { + "jar": "ef6b65d640b192b43d5bbeef597275e00dc9fbd9a990059d03769f7259d0bcea" + }, + "version": "3.11" + }, + "io.avaje:avaje-jsonb-inject-plugin": { + "shasums": { + "jar": "bc45b5e6b0624921a2cb2f9da69c31cf068619609857e1422332ce3bef022377" + }, + "version": "3.11" + }, + "io.avaje:avaje-spi-core": { + "shasums": { + "jar": "32ba914b9bed7da26fa40743fda4f300c393df020f76aa0176f817829c3918c5" + }, + "version": "2.16" + }, + "io.avaje:avaje-spi-service": { + "shasums": { + "jar": "8d8826d60e7fcebbb7b7a4f0832878cd12c280d9829dc6a206034b9ae1cfa73d" + }, + "version": "2.16" + }, "junit:junit": { "shasums": { "jar": "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3" @@ -314,10 +332,6 @@ } }, "dependencies": { - "com.fasterxml.jackson.core:jackson-databind": [ - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-core" - ], "com.google.auto:auto-common": [ "com.google.guava:guava" ], @@ -354,6 +368,16 @@ "org.hamcrest:hamcrest-library", "org.mockito:mockito-core" ], + "io.avaje:avaje-jsonb": [ + "io.avaje:avaje-json-core", + "io.avaje:avaje-jsonb-inject-plugin" + ], + "io.avaje:avaje-jsonb-generator": [ + "io.avaje:avaje-spi-service" + ], + "io.avaje:avaje-spi-service": [ + "io.avaje:avaje-spi-core" + ], "junit:junit": [ "org.hamcrest:hamcrest-core" ], @@ -442,50 +466,6 @@ ] }, "packages": { - "com.fasterxml.jackson.core:jackson-annotations": [ - "com.fasterxml.jackson.annotation" - ], - "com.fasterxml.jackson.core:jackson-core": [ - "com.fasterxml.jackson.core", - "com.fasterxml.jackson.core.async", - "com.fasterxml.jackson.core.base", - "com.fasterxml.jackson.core.exc", - "com.fasterxml.jackson.core.filter", - "com.fasterxml.jackson.core.format", - "com.fasterxml.jackson.core.internal.shaded.fdp.v2_19_2", - "com.fasterxml.jackson.core.io", - "com.fasterxml.jackson.core.io.schubfach", - "com.fasterxml.jackson.core.json", - "com.fasterxml.jackson.core.json.async", - "com.fasterxml.jackson.core.sym", - "com.fasterxml.jackson.core.type", - "com.fasterxml.jackson.core.util" - ], - "com.fasterxml.jackson.core:jackson-databind": [ - "com.fasterxml.jackson.databind", - "com.fasterxml.jackson.databind.annotation", - "com.fasterxml.jackson.databind.cfg", - "com.fasterxml.jackson.databind.deser", - "com.fasterxml.jackson.databind.deser.impl", - "com.fasterxml.jackson.databind.deser.std", - "com.fasterxml.jackson.databind.exc", - "com.fasterxml.jackson.databind.ext", - "com.fasterxml.jackson.databind.introspect", - "com.fasterxml.jackson.databind.jdk14", - "com.fasterxml.jackson.databind.json", - "com.fasterxml.jackson.databind.jsonFormatVisitors", - "com.fasterxml.jackson.databind.jsonschema", - "com.fasterxml.jackson.databind.jsontype", - "com.fasterxml.jackson.databind.jsontype.impl", - "com.fasterxml.jackson.databind.module", - "com.fasterxml.jackson.databind.node", - "com.fasterxml.jackson.databind.ser", - "com.fasterxml.jackson.databind.ser.impl", - "com.fasterxml.jackson.databind.ser.std", - "com.fasterxml.jackson.databind.type", - "com.fasterxml.jackson.databind.util", - "com.fasterxml.jackson.databind.util.internal" - ], "com.google.auto.value:auto-value": [ "autovalue.shaded.com.google.auto.common", "autovalue.shaded.com.google.auto.service", @@ -647,6 +627,31 @@ "org.opencv.video", "org.opencv.videoio" ], + "io.avaje:avaje-json-core": [ + "io.avaje.json", + "io.avaje.json.core", + "io.avaje.json.mapper", + "io.avaje.json.stream", + "io.avaje.json.stream.core", + "io.avaje.json.view" + ], + "io.avaje:avaje-jsonb": [ + "io.avaje.jsonb", + "io.avaje.jsonb.core", + "io.avaje.jsonb.spi" + ], + "io.avaje:avaje-jsonb-generator": [ + "io.avaje.jsonb.generator" + ], + "io.avaje:avaje-jsonb-inject-plugin": [ + "io.avaje.jsonb.inject" + ], + "io.avaje:avaje-spi-core": [ + "io.avaje.spi.internal" + ], + "io.avaje:avaje-spi-service": [ + "io.avaje.spi" + ], "junit:junit": [ "junit.extensions", "junit.framework", @@ -1178,9 +1183,6 @@ }, "repositories": { "https://frcmaven.wpi.edu/artifactory/release/": [ - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-core", - "com.fasterxml.jackson.core:jackson-databind", "com.google.auto.value:auto-value", "com.google.auto.value:auto-value-annotations", "com.google.auto:auto-common", @@ -1196,6 +1198,12 @@ "com.googlecode.junit-toolbox:junit-toolbox", "commons-io:commons-io", "edu.wpi.first.thirdparty.frc2025.opencv:opencv-java", + "io.avaje:avaje-json-core", + "io.avaje:avaje-jsonb", + "io.avaje:avaje-jsonb-generator", + "io.avaje:avaje-jsonb-inject-plugin", + "io.avaje:avaje-spi-core", + "io.avaje:avaje-spi-service", "junit:junit", "net.bytebuddy:byte-buddy", "net.bytebuddy:byte-buddy-agent", @@ -1231,9 +1239,6 @@ "us.hebi.quickbuf:quickbuf-runtime" ], "https://repo1.maven.org/maven2/": [ - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-core", - "com.fasterxml.jackson.core:jackson-databind", "com.google.auto.value:auto-value", "com.google.auto.value:auto-value-annotations", "com.google.auto:auto-common", @@ -1249,6 +1254,12 @@ "com.googlecode.junit-toolbox:junit-toolbox", "commons-io:commons-io", "edu.wpi.first.thirdparty.frc2025.opencv:opencv-java", + "io.avaje:avaje-json-core", + "io.avaje:avaje-jsonb", + "io.avaje:avaje-jsonb-generator", + "io.avaje:avaje-jsonb-inject-plugin", + "io.avaje:avaje-spi-core", + "io.avaje:avaje-spi-service", "junit:junit", "net.bytebuddy:byte-buddy", "net.bytebuddy:byte-buddy-agent", @@ -1285,16 +1296,6 @@ ] }, "services": { - "com.fasterxml.jackson.core:jackson-core": { - "com.fasterxml.jackson.core.JsonFactory": [ - "com.fasterxml.jackson.core.JsonFactory" - ] - }, - "com.fasterxml.jackson.core:jackson-databind": { - "com.fasterxml.jackson.core.ObjectCodec": [ - "com.fasterxml.jackson.databind.ObjectMapper" - ] - }, "com.google.auto.value:auto-value": { "autovalue.shaded.kotlinx.metadata.impl.extensions.MetadataExtensions": [ "autovalue.shaded.kotlinx.metadata.jvm.impl.JvmMetadataExtensions" @@ -1319,6 +1320,26 @@ "com.google.auto.value.processor.AutoValueProcessor" ] }, + "io.avaje:avaje-jsonb-generator": { + "javax.annotation.processing.Processor": [ + "io.avaje.jsonb.generator.JsonbProcessor" + ] + }, + "io.avaje:avaje-jsonb-inject-plugin": { + "io.avaje.inject.spi.InjectExtension": [ + "io.avaje.jsonb.inject.DefaultJsonbProvider" + ] + }, + "io.avaje:avaje-spi-core": { + "javax.annotation.processing.Processor": [ + "io.avaje.spi.internal.ServiceProcessor" + ] + }, + "io.avaje:avaje-spi-service": { + "javax.annotation.processing.Processor": [ + "io.avaje.spi.internal.ServiceProcessor" + ] + }, "org.junit.jupiter:junit-jupiter-engine": { "org.junit.platform.engine.TestEngine": [ "org.junit.jupiter.engine.JupiterTestEngine" diff --git a/wpilibj/CMakeLists.txt b/wpilibj/CMakeLists.txt index a8785b9f30..fef5983fcc 100644 --- a/wpilibj/CMakeLists.txt +++ b/wpilibj/CMakeLists.txt @@ -24,7 +24,7 @@ if(WITH_JAVA) file(GLOB_RECURSE JAVA_SOURCES src/main/java/*.java src/generated/main/java/*.java) file(GLOB EJML_JARS "${WPILIB_BINARY_DIR}/wpimath/thirdparty/ejml/*.jar") - file(GLOB JACKSON_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/jackson/*.jar") + file(GLOB AVAJE_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/avaje/*.jar") add_jar( wpilibj_jar @@ -34,7 +34,7 @@ if(WITH_JAVA) hal_jar ntcore_jar ${EJML_JARS} - ${JACKSON_JARS} + ${AVAJE_JARS} ${OPENCV_JAR_FILE} cscore_jar cameraserver_jar diff --git a/wpimath/BUILD.bazel b/wpimath/BUILD.bazel index bd2e92a1c7..c318446a95 100644 --- a/wpimath/BUILD.bazel +++ b/wpimath/BUILD.bazel @@ -242,15 +242,17 @@ wpilib_jni_java_library( maven_artifact_name = "wpimath-java", maven_group_id = "org.wpilib.wpimath", native_libs = [":wpimathjni"], + plugins = [ + "//:avaje_jsonb_generator", + ], resource_strip_prefix = "wpimath/src/main/proto", resources = glob(["src/main/proto/**"]), visibility = ["//visibility:public"], deps = [ "//wpiunits:wpiunits-java", "//wpiutil:wpiutil-java", - "@maven//:com_fasterxml_jackson_core_jackson_annotations", - "@maven//:com_fasterxml_jackson_core_jackson_core", - "@maven//:com_fasterxml_jackson_core_jackson_databind", + "@maven//:io_avaje_avaje_json_core", + "@maven//:io_avaje_avaje_jsonb", "@maven//:org_ejml_ejml_core", "@maven//:org_ejml_ejml_ddense", "@maven//:org_ejml_ejml_simple", diff --git a/wpimath/CMakeLists.txt b/wpimath/CMakeLists.txt index 73d5210913..5160275080 100644 --- a/wpimath/CMakeLists.txt +++ b/wpimath/CMakeLists.txt @@ -64,7 +64,7 @@ if(WITH_JAVA) endif() file(GLOB EJML_JARS "${WPILIB_BINARY_DIR}/wpimath/thirdparty/ejml/*.jar") - file(GLOB JACKSON_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/jackson/*.jar") + file(GLOB AVAJE_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/avaje/*.jar") file(GLOB QUICKBUF_JAR ${WPILIB_BINARY_DIR}/wpiutil/thirdparty/quickbuf/*.jar) set(CMAKE_JNI_TARGET true) @@ -74,7 +74,7 @@ if(WITH_JAVA) add_jar( wpimath_jar ${JAVA_SOURCES} - INCLUDE_JARS wpiutil_jar wpiunits_jar ${EJML_JARS} ${JACKSON_JARS} ${QUICKBUF_JAR} + INCLUDE_JARS wpiutil_jar wpiunits_jar ${EJML_JARS} ${AVAJE_JARS} ${QUICKBUF_JAR} OUTPUT_NAME wpimath OUTPUT_DIR ${WPILIB_BINARY_DIR}/${java_lib_dest} GENERATE_NATIVE_HEADERS wpimath_jni_headers diff --git a/wpimath/build.gradle b/wpimath/build.gradle index 63c2a51a5f..92fb447fd7 100644 --- a/wpimath/build.gradle +++ b/wpimath/build.gradle @@ -88,9 +88,10 @@ nativeUtils.exportsConfigs { } dependencies { + annotationProcessor libs.avaje.jsonb.generator api project(":wpiunits") + api libs.avaje.jsonb api libs.bundles.ejml - api libs.bundles.jackson api libs.quickbuf.runtime } diff --git a/wpimath/src/main/java/org/wpilib/math/geometry/Pose2d.java b/wpimath/src/main/java/org/wpilib/math/geometry/Pose2d.java index 460cd85261..e2b1eebf8f 100644 --- a/wpimath/src/main/java/org/wpilib/math/geometry/Pose2d.java +++ b/wpimath/src/main/java/org/wpilib/math/geometry/Pose2d.java @@ -6,10 +6,7 @@ package org.wpilib.math.geometry; import static org.wpilib.units.Units.Meters; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; +import io.avaje.jsonb.Json; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -26,8 +23,7 @@ import org.wpilib.util.protobuf.ProtobufSerializable; import org.wpilib.util.struct.StructSerializable; /** Represents a 2D pose containing translational and rotational elements. */ -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE) +@Json public class Pose2d implements Interpolatable, ProtobufSerializable, StructSerializable { /** * A preallocated Pose2d representing the origin. @@ -36,7 +32,10 @@ public class Pose2d implements Interpolatable, ProtobufSerializable, Str */ public static final Pose2d kZero = new Pose2d(); + @Json.Property("translation") private final Translation2d m_translation; + + @Json.Property("rotation") private final Rotation2d m_rotation; /** Constructs a pose at the origin facing toward the positive X axis. */ @@ -51,10 +50,8 @@ public class Pose2d implements Interpolatable, ProtobufSerializable, Str * @param translation The translational component of the pose. * @param rotation The rotational component of the pose. */ - @JsonCreator - public Pose2d( - @JsonProperty(required = true, value = "translation") Translation2d translation, - @JsonProperty(required = true, value = "rotation") Rotation2d rotation) { + @Json.Creator + public Pose2d(Translation2d translation, Rotation2d rotation) { m_translation = translation; m_rotation = rotation; } @@ -129,7 +126,6 @@ public class Pose2d implements Interpolatable, ProtobufSerializable, Str * * @return The translational component of the pose. */ - @JsonProperty public Translation2d getTranslation() { return m_translation; } @@ -175,7 +171,6 @@ public class Pose2d implements Interpolatable, ProtobufSerializable, Str * * @return The rotational component of the pose. */ - @JsonProperty public Rotation2d getRotation() { return m_rotation; } diff --git a/wpimath/src/main/java/org/wpilib/math/geometry/Pose3d.java b/wpimath/src/main/java/org/wpilib/math/geometry/Pose3d.java index f27a6367ac..57d5c389fb 100644 --- a/wpimath/src/main/java/org/wpilib/math/geometry/Pose3d.java +++ b/wpimath/src/main/java/org/wpilib/math/geometry/Pose3d.java @@ -6,10 +6,7 @@ package org.wpilib.math.geometry; import static org.wpilib.units.Units.Meters; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; +import io.avaje.jsonb.Json; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -26,8 +23,7 @@ import org.wpilib.util.protobuf.ProtobufSerializable; import org.wpilib.util.struct.StructSerializable; /** Represents a 3D pose containing translational and rotational elements. */ -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE) +@Json public class Pose3d implements Interpolatable, ProtobufSerializable, StructSerializable { /** * A preallocated Pose3d representing the origin. @@ -36,7 +32,10 @@ public class Pose3d implements Interpolatable, ProtobufSerializable, Str */ public static final Pose3d kZero = new Pose3d(); + @Json.Property("translation") private final Translation3d m_translation; + + @Json.Property("rotation") private final Rotation3d m_rotation; /** Constructs a pose at the origin facing toward the positive X axis. */ @@ -51,10 +50,8 @@ public class Pose3d implements Interpolatable, ProtobufSerializable, Str * @param translation The translational component of the pose. * @param rotation The rotational component of the pose. */ - @JsonCreator - public Pose3d( - @JsonProperty(required = true, value = "translation") Translation3d translation, - @JsonProperty(required = true, value = "rotation") Rotation3d rotation) { + @Json.Creator + public Pose3d(Translation3d translation, Rotation3d rotation) { m_translation = translation; m_rotation = rotation; } @@ -143,7 +140,6 @@ public class Pose3d implements Interpolatable, ProtobufSerializable, Str * * @return The translational component of the pose. */ - @JsonProperty public Translation3d getTranslation() { return m_translation; } @@ -207,7 +203,6 @@ public class Pose3d implements Interpolatable, ProtobufSerializable, Str * * @return The rotational component of the pose. */ - @JsonProperty public Rotation3d getRotation() { return m_rotation; } diff --git a/wpimath/src/main/java/org/wpilib/math/geometry/Quaternion.java b/wpimath/src/main/java/org/wpilib/math/geometry/Quaternion.java index 1334b8fcb4..076caa49f4 100644 --- a/wpimath/src/main/java/org/wpilib/math/geometry/Quaternion.java +++ b/wpimath/src/main/java/org/wpilib/math/geometry/Quaternion.java @@ -4,10 +4,7 @@ package org.wpilib.math.geometry; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; +import io.avaje.jsonb.Json; import java.util.Objects; import org.wpilib.math.geometry.proto.QuaternionProto; import org.wpilib.math.geometry.struct.QuaternionStruct; @@ -18,16 +15,15 @@ import org.wpilib.util.protobuf.ProtobufSerializable; import org.wpilib.util.struct.StructSerializable; /** Represents a quaternion. */ -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE) +@Json public class Quaternion implements ProtobufSerializable, StructSerializable { // Scalar r in versor form - private final double m_w; + @Json.Ignore private final double m_w; // Vector v in versor form - private final double m_x; - private final double m_y; - private final double m_z; + @Json.Ignore private final double m_x; + @Json.Ignore private final double m_y; + @Json.Ignore private final double m_z; /** Constructs a quaternion with a default angle of 0 degrees. */ public Quaternion() { @@ -45,12 +41,12 @@ public class Quaternion implements ProtobufSerializable, StructSerializable { * @param y Y component of the quaternion. * @param z Z component of the quaternion. */ - @JsonCreator + @Json.Creator public Quaternion( - @JsonProperty(required = true, value = "W") double w, - @JsonProperty(required = true, value = "X") double x, - @JsonProperty(required = true, value = "Y") double y, - @JsonProperty(required = true, value = "Z") double z) { + @Json.Alias("W") double w, + @Json.Alias("X") double x, + @Json.Alias("Y") double y, + @Json.Alias("Z") double z) { m_w = w; m_x = x; m_y = y; @@ -291,7 +287,7 @@ public class Quaternion implements ProtobufSerializable, StructSerializable { * * @return W component of the quaternion. */ - @JsonProperty(value = "W") + @Json.Property(value = "W") public double getW() { return m_w; } @@ -301,7 +297,7 @@ public class Quaternion implements ProtobufSerializable, StructSerializable { * * @return X component of the quaternion. */ - @JsonProperty(value = "X") + @Json.Property(value = "X") public double getX() { return m_x; } @@ -311,7 +307,7 @@ public class Quaternion implements ProtobufSerializable, StructSerializable { * * @return Y component of the quaternion. */ - @JsonProperty(value = "Y") + @Json.Property(value = "Y") public double getY() { return m_y; } @@ -321,7 +317,7 @@ public class Quaternion implements ProtobufSerializable, StructSerializable { * * @return Z component of the quaternion. */ - @JsonProperty(value = "Z") + @Json.Property(value = "Z") public double getZ() { return m_z; } diff --git a/wpimath/src/main/java/org/wpilib/math/geometry/Rotation2d.java b/wpimath/src/main/java/org/wpilib/math/geometry/Rotation2d.java index 5ffcd01ecc..ec64a2c50a 100644 --- a/wpimath/src/main/java/org/wpilib/math/geometry/Rotation2d.java +++ b/wpimath/src/main/java/org/wpilib/math/geometry/Rotation2d.java @@ -6,10 +6,7 @@ package org.wpilib.math.geometry; import static org.wpilib.units.Units.Radians; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; +import io.avaje.jsonb.Json; import java.util.Objects; import org.wpilib.math.geometry.proto.Rotation2dProto; import org.wpilib.math.geometry.struct.Rotation2dStruct; @@ -27,8 +24,7 @@ import org.wpilib.util.struct.StructSerializable; /** * A rotation in a 2D coordinate frame represented by a point on the unit circle (cosine and sine). */ -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE) +@Json public class Rotation2d implements Interpolatable, ProtobufSerializable, StructSerializable { /** @@ -80,8 +76,8 @@ public class Rotation2d */ public static final Rotation2d k180deg = kPi; - private final double m_cos; - private final double m_sin; + @Json.Ignore private final double m_cos; + @Json.Ignore private final double m_sin; /** Constructs a Rotation2d with a default angle of 0 degrees. */ public Rotation2d() { @@ -94,8 +90,8 @@ public class Rotation2d * * @param value The value of the angle in radians. */ - @JsonCreator - public Rotation2d(@JsonProperty(required = true, value = "radians") double value) { + @Json.Creator + public Rotation2d(@Json.Alias(value = "radians") double value) { m_cos = Math.cos(value); m_sin = Math.sin(value); } @@ -300,7 +296,7 @@ public class Rotation2d * * @return The radian value of the Rotation2d constrained within [-π, π]. */ - @JsonProperty + @Json.Property("radians") public double getRadians() { return Math.atan2(m_sin, m_cos); } diff --git a/wpimath/src/main/java/org/wpilib/math/geometry/Rotation3d.java b/wpimath/src/main/java/org/wpilib/math/geometry/Rotation3d.java index e0e9a43fb9..9d3ccbb486 100644 --- a/wpimath/src/main/java/org/wpilib/math/geometry/Rotation3d.java +++ b/wpimath/src/main/java/org/wpilib/math/geometry/Rotation3d.java @@ -6,10 +6,7 @@ package org.wpilib.math.geometry; import static org.wpilib.units.Units.Radians; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; +import io.avaje.jsonb.Json; import java.util.Objects; import org.wpilib.math.geometry.proto.Rotation3dProto; import org.wpilib.math.geometry.struct.Rotation3dStruct; @@ -68,8 +65,7 @@ import org.wpilib.util.struct.StructSerializable; * rotation. A neat property is that applying a series of rotations extrinsically is the same as * applying the same series in the opposite order intrinsically. */ -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE) +@Json public class Rotation3d implements Interpolatable, ProtobufSerializable, StructSerializable { /** @@ -79,6 +75,7 @@ public class Rotation3d */ public static final Rotation3d kZero = new Rotation3d(); + @Json.Property("quaternion") private final Quaternion m_q; /** Constructs a Rotation3d representing no rotation. */ @@ -91,8 +88,8 @@ public class Rotation3d * * @param q The quaternion. */ - @JsonCreator - public Rotation3d(@JsonProperty(required = true, value = "quaternion") Quaternion q) { + @Json.Creator + public Rotation3d(@Json.Alias("quaternion") Quaternion q) { m_q = q.normalize(); } @@ -393,7 +390,6 @@ public class Rotation3d * * @return The quaternion representation of the Rotation3d. */ - @JsonProperty(value = "quaternion") public Quaternion getQuaternion() { return m_q; } diff --git a/wpimath/src/main/java/org/wpilib/math/geometry/Translation2d.java b/wpimath/src/main/java/org/wpilib/math/geometry/Translation2d.java index 1e5e7574f1..b2359ca256 100644 --- a/wpimath/src/main/java/org/wpilib/math/geometry/Translation2d.java +++ b/wpimath/src/main/java/org/wpilib/math/geometry/Translation2d.java @@ -6,10 +6,7 @@ package org.wpilib.math.geometry; import static org.wpilib.units.Units.Meters; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; +import io.avaje.jsonb.Json; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -31,8 +28,7 @@ import org.wpilib.util.struct.StructSerializable; *

This assumes that you are using conventional mathematical axes. When the robot is at the * origin facing in the positive X direction, forward is positive X and left is positive Y. */ -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE) +@Json public class Translation2d implements Interpolatable, ProtobufSerializable, StructSerializable { /** @@ -42,7 +38,10 @@ public class Translation2d */ public static final Translation2d kZero = new Translation2d(); + @Json.Property("x") private final double m_x; + + @Json.Property("y") private final double m_y; /** Constructs a Translation2d with X and Y components equal to zero. */ @@ -56,10 +55,8 @@ public class Translation2d * @param x The x component of the translation. * @param y The y component of the translation. */ - @JsonCreator - public Translation2d( - @JsonProperty(required = true, value = "x") double x, - @JsonProperty(required = true, value = "y") double y) { + @Json.Creator + public Translation2d(double x, double y) { m_x = x; m_y = y; } @@ -130,7 +127,6 @@ public class Translation2d * * @return The X component of the translation. */ - @JsonProperty public double getX() { return m_x; } @@ -140,7 +136,6 @@ public class Translation2d * * @return The Y component of the translation. */ - @JsonProperty public double getY() { return m_y; } diff --git a/wpimath/src/main/java/org/wpilib/math/geometry/Translation3d.java b/wpimath/src/main/java/org/wpilib/math/geometry/Translation3d.java index 7b72d52aab..146f749193 100644 --- a/wpimath/src/main/java/org/wpilib/math/geometry/Translation3d.java +++ b/wpimath/src/main/java/org/wpilib/math/geometry/Translation3d.java @@ -6,10 +6,7 @@ package org.wpilib.math.geometry; import static org.wpilib.units.Units.Meters; -import com.fasterxml.jackson.annotation.JsonAutoDetect; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; +import io.avaje.jsonb.Json; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -32,8 +29,7 @@ import org.wpilib.util.struct.StructSerializable; * origin facing in the positive X direction, forward is positive X, left is positive Y, and up is * positive Z. */ -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE) +@Json public class Translation3d implements Interpolatable, ProtobufSerializable, StructSerializable { /** @@ -43,8 +39,13 @@ public class Translation3d */ public static final Translation3d kZero = new Translation3d(); + @Json.Property("x") private final double m_x; + + @Json.Property("y") private final double m_y; + + @Json.Property("z") private final double m_z; /** Constructs a Translation3d with X, Y, and Z components equal to zero. */ @@ -59,11 +60,8 @@ public class Translation3d * @param y The y component of the translation. * @param z The z component of the translation. */ - @JsonCreator - public Translation3d( - @JsonProperty(required = true, value = "x") double x, - @JsonProperty(required = true, value = "y") double y, - @JsonProperty(required = true, value = "z") double z) { + @Json.Creator + public Translation3d(double x, double y, double z) { m_x = x; m_y = y; m_z = z; @@ -152,7 +150,6 @@ public class Translation3d * * @return The X component of the translation. */ - @JsonProperty public double getX() { return m_x; } @@ -162,7 +159,6 @@ public class Translation3d * * @return The Y component of the translation. */ - @JsonProperty public double getY() { return m_y; } @@ -172,7 +168,6 @@ public class Translation3d * * @return The Z component of the translation. */ - @JsonProperty public double getZ() { return m_z; } diff --git a/wpimath/src/main/java/org/wpilib/math/trajectory/Trajectory.java b/wpimath/src/main/java/org/wpilib/math/trajectory/Trajectory.java index ae16d0f1f3..9455dbc1e1 100644 --- a/wpimath/src/main/java/org/wpilib/math/trajectory/Trajectory.java +++ b/wpimath/src/main/java/org/wpilib/math/trajectory/Trajectory.java @@ -4,7 +4,7 @@ package org.wpilib.math.trajectory; -import com.fasterxml.jackson.annotation.JsonProperty; +import io.avaje.jsonb.Json; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -256,23 +256,23 @@ public class Trajectory implements ProtobufSerializable { public static final TrajectoryStateProto proto = new TrajectoryStateProto(); /** The time elapsed since the beginning of the trajectory in seconds. */ - @JsonProperty("time") + @Json.Property("time") public double time; /** The velocity at that point of the trajectory in meters per second. */ - @JsonProperty("velocity") + @Json.Property("velocity") public double velocity; /** The acceleration at that point of the trajectory in m/s². */ - @JsonProperty("acceleration") + @Json.Property("acceleration") public double acceleration; /** The pose at that point of the trajectory. */ - @JsonProperty("pose") + @Json.Property("pose") public Pose2d pose; /** The curvature at that point of the trajectory in rad/m. */ - @JsonProperty("curvature") + @Json.Property("curvature") public double curvature; /** Default constructor. */ diff --git a/wpiutil/BUILD.bazel b/wpiutil/BUILD.bazel index 39b3937519..0d31c0b645 100644 --- a/wpiutil/BUILD.bazel +++ b/wpiutil/BUILD.bazel @@ -279,9 +279,6 @@ wpilib_jni_java_library( native_libs = [":wpiutiljni"], visibility = ["//visibility:public"], deps = [ - "@maven//:com_fasterxml_jackson_core_jackson_annotations", - "@maven//:com_fasterxml_jackson_core_jackson_core", - "@maven//:com_fasterxml_jackson_core_jackson_databind", "@maven//:us_hebi_quickbuf_quickbuf_runtime", ], ) diff --git a/wpiutil/CMakeLists.txt b/wpiutil/CMakeLists.txt index 70ee007590..168943ba20 100644 --- a/wpiutil/CMakeLists.txt +++ b/wpiutil/CMakeLists.txt @@ -12,29 +12,41 @@ file(GLOB wpiutil_jni_src src/main/native/cpp/jni/WPIUtilJNI.cpp) if(WITH_JAVA) include(UseJava) - if(NOT EXISTS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/jackson/jackson-core-2.19.2.jar") + if(NOT EXISTS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/avaje/avaje-jsonb-3.11.jar") set(BASE_URL "https://search.maven.org/remotecontent?filepath=") - set(JAR_ROOT "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/jackson") + set(JAR_ROOT "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/avaje") - message(STATUS "Downloading Jackson jarfiles...") + message(STATUS "Downloading Avaje jarfiles...") download_and_check( - "${BASE_URL}com/fasterxml/jackson/core/jackson-core/2.19.2/jackson-core-2.19.2.jar" - "${JAR_ROOT}/jackson-core-2.19.2.jar" + "${BASE_URL}io/avaje/avaje-jsonb/3.11/avaje-jsonb-3.11.jar" + "${JAR_ROOT}/avaje-jsonb-3.11.jar" ) download_and_check( - "${BASE_URL}com/fasterxml/jackson/core/jackson-databind/2.19.2/jackson-databind-2.19.2.jar" - "${JAR_ROOT}/jackson-databind-2.19.2.jar" + "${BASE_URL}io/avaje/avaje-json-core/3.11/avaje-json-core-3.11.jar" + "${JAR_ROOT}/avaje-json-core-3.11.jar" ) download_and_check( - "${BASE_URL}com/fasterxml/jackson/core/jackson-annotations/2.19.2/jackson-annotations-2.19.2.jar" - "${JAR_ROOT}/jackson-annotations-2.19.2.jar" + "${BASE_URL}io/avaje/avaje-jsonb-inject-plugin/3.11/avaje-jsonb-inject-plugin-3.11.jar" + "${JAR_ROOT}/avaje-jsonb-inject-plugin-3.11.jar" + ) + download_and_check( + "${BASE_URL}io/avaje/avaje-jsonb-generator/3.11/avaje-jsonb-generator-3.11.jar" + "${JAR_ROOT}/avaje-jsonb-generator-3.11.jar" + ) + download_and_check( + "${BASE_URL}io/avaje/avaje-spi-service/2.16/avaje-spi-service-2.16.jar" + "${JAR_ROOT}/avaje-spi-service-2.16.jar" + ) + download_and_check( + "${BASE_URL}io/avaje/avaje-spi-core/2.16/avaje-spi-core-2.16.jar" + "${JAR_ROOT}/avaje-spi-core-2.16.jar" ) message(STATUS "All files downloaded.") endif() - file(GLOB JACKSON_JARS ${WPILIB_BINARY_DIR}/wpiutil/thirdparty/jackson/*.jar) + file(GLOB AVAJE_JARS ${WPILIB_BINARY_DIR}/wpiutil/thirdparty/avaje/*.jar) if(NOT EXISTS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/quickbuf/quickbuf-runtime-1.4.jar") set(BASE_URL "https://search.maven.org/remotecontent?filepath=") @@ -58,7 +70,7 @@ if(WITH_JAVA) add_jar( wpiutil_jar ${JAVA_SOURCES} - INCLUDE_JARS ${JACKSON_JARS} ${QUICKBUF_JAR} + INCLUDE_JARS ${AVAJE_JARS} ${QUICKBUF_JAR} OUTPUT_NAME wpiutil OUTPUT_DIR ${WPILIB_BINARY_DIR}/${java_lib_dest} GENERATE_NATIVE_HEADERS wpiutil_jni_headers diff --git a/wpiutil/build.gradle b/wpiutil/build.gradle index ea4c7aec36..3b117b0871 100644 --- a/wpiutil/build.gradle +++ b/wpiutil/build.gradle @@ -285,6 +285,7 @@ model { } dependencies { - api libs.bundles.jackson + annotationProcessor libs.avaje.jsonb.generator + api libs.avaje.jsonb api libs.quickbuf.runtime }