Replace Error Prone annotations with local annotations and JSR-305 with JSpecify.

Bundling `error_prone_annotations` in particular into the Bazel `Runner_deploy.jar` causes one-version violations for `java_test` targets that depend on a different version of `error_prone_annotations`: See https://github.com/google/inject-common/pull/82.

And overall, it's nice to put as little on the classpath as we can: It helps people who want to test how their code behaves with minimal dependencies, and it avoids the challenges around JSR-305 in particular. Here are some past notes about test-runner deps:
- https://github.com/bazelbuild/bazel/issues/1150
- https://github.com/bazelbuild/bazel/issues/1634
- https://github.com/bazelbuild/bazel/issues/2146
- https://github.com/bazelbuild/bazel/blob/a369be1fdb06b465ad272891c987b264659b0349/src/main/java/com/google/devtools/build/lib/rules/java/JavaOptions.java#L194-L206

PiperOrigin-RevId: 1000079080
Change-Id: I766a7756a9abc1b0f707c18257451f3c178831de
diff --git a/MODULE.bazel b/MODULE.bazel
index 87d0cb2..42cb19b 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -256,6 +256,7 @@
         "org.brotli:dec:0.1.2",
         "org.checkerframework:checker-qual:3.49.3",
         "org.commonmark:commonmark:0.25.0",
+        "org.jspecify:jspecify:1.0.1",
         "org.openjdk.jmh:jmh-core:1.37",
         "org.openjdk.jmh:jmh-generator-annprocess:1.37",
         "org.openjdk.jol:jol-core:0.17",
diff --git a/maven_install.json b/maven_install.json
index 5aed71a..b881749 100644
--- a/maven_install.json
+++ b/maven_install.json
@@ -1,6 +1,6 @@
 {
   "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
-  "__INPUT_ARTIFACTS_HASH": -1187938192,
+  "__INPUT_ARTIFACTS_HASH": 914107018,
   "__RESOLVED_ARTIFACTS_HASH": -1539311347,
   "conflict_resolution": {
     "com.google.guava:guava:33.5.0-jre": "com.google.guava:guava:33.7.1-jre",
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/BUILD b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/BUILD
index ac140d7..9bd2dc2 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/BUILD
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/BUILD
@@ -19,8 +19,7 @@
         "//src/java_tools/junitrunner/java/com/google/testing/junit/runner/model",
         "//src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding",
         "//src/java_tools/junitrunner/java/com/google/testing/junit/runner/util",
-        "//third_party/java/error_prone:annotations",
-        "//third_party/java/jsr305_annotations",
+        "//third_party/java/jspecify_annotations",
         "//third_party/java/junit:not-testonly",
     ],
 )
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/CanIgnoreReturnValue.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/CanIgnoreReturnValue.java
new file mode 100644
index 0000000..f75bba5
--- /dev/null
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/CanIgnoreReturnValue.java
@@ -0,0 +1,25 @@
+// Copyright 2026 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.junit4;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(CLASS)
+@Target(METHOD)
+@interface CanIgnoreReturnValue {}
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Bazel.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Bazel.java
index b47377e..87d2ce5 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Bazel.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Bazel.java
@@ -14,7 +14,6 @@
 
 package com.google.testing.junit.runner.junit4;
 
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
 import com.google.testing.junit.runner.internal.junit4.CancellableRequestFactory;
 import com.google.testing.junit.runner.internal.junit4.MemoizingRequest;
 import com.google.testing.junit.runner.model.AntXmlResultWriter;
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Config.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Config.java
index 04588ab..5694385 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Config.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Config.java
@@ -17,7 +17,7 @@
 import java.nio.file.FileSystems;
 import java.nio.file.Path;
 import java.util.Properties;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
 
 /**
  * Configuration for the JUnit4 test runner.
@@ -29,7 +29,7 @@
   private final boolean testRunnerFailFast;
   private final String testIncludeFilterRegexp;
   private final String testExcludeFilterRegexp;
-  @Nullable private final Path xmlOutputPath;
+  private final @Nullable Path xmlOutputPath;
   private final String junitApiVersion;
 
   private static final String XML_OUTPUT_FILE_ENV_VAR = "XML_OUTPUT_FILE";
@@ -78,11 +78,8 @@
     junitApiVersion = systemProperties.getProperty(JUNIT_API_VERSION_PROPERTY, "1").trim();
   }
 
-  /**
-   * Returns the XML output path, or null if not specified.
-   */
-  @Nullable
-  public Path getXmlOutputPath() {
+  /** Returns the XML output path, or null if not specified. */
+  public @Nullable Path getXmlOutputPath() {
     if (xmlOutputPath == null) {
       String envXmlOutputPath = System.getenv(XML_OUTPUT_FILE_ENV_VAR);
       return
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Options.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Options.java
index 72acd20..30525cc6 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Options.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Options.java
@@ -19,7 +19,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
 
 /**
  * Simple options parser for JUnit 4.
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Runner.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Runner.java
index 8988b9a..73baa9b 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Runner.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4Runner.java
@@ -25,7 +25,7 @@
 import java.io.PrintStream;
 import java.util.Set;
 import java.util.function.Supplier;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
 import org.junit.internal.runners.ErrorReportingRunner;
 import org.junit.runner.Description;
 import org.junit.runner.JUnitCore;
@@ -153,35 +153,35 @@
   }
 
   /**
-   * Apply command-line and sharding filters, if appropriate.<p>
+   * Apply command-line and sharding filters, if appropriate.
    *
-   * Note that this is carefully written to avoid running into potential
-   * problems with the way runners implement filtering. The JavaDoc for
-   * {@link org.junit.runner.manipulation.Filterable} states that tests that
-   * don't match the filter should be removed, which implies if you apply two
-   * filters, you will always get an intersection of the two. Unfortunately, the
-   * filtering implementation of {@link org.junit.runners.ParentRunner} does not
-   * do this, and instead uses a "last applied filter wins" strategy.<p>
+   * <p>Note that this is carefully written to avoid running into potential problems with the way
+   * runners implement filtering. The JavaDoc for {@link org.junit.runner.manipulation.Filterable}
+   * states that tests that don't match the filter should be removed, which implies if you apply two
+   * filters, you will always get an intersection of the two. Unfortunately, the filtering
+   * implementation of {@link org.junit.runners.ParentRunner} does not do this, and instead uses a
+   * "last applied filter wins" strategy.
    *
-   * We work around potential problems by ensuring that if we apply a second
-   * filter, the filter is more restrictive than the first. We also assume that
-   * if filtering fails, the request will have a runner that is a
-   * {@link ErrorReportingRunner}. Luckily, we can cover this with tests to make
-   * sure we don't break if JUnit changes in the future.
+   * <p>We work around potential problems by ensuring that if we apply a second filter, the filter
+   * is more restrictive than the first. We also assume that if filtering fails, the request will
+   * have a runner that is a {@link ErrorReportingRunner}. Luckily, we can cover this with tests to
+   * make sure we don't break if JUnit changes in the future.
    *
    * @param request Request to filter
    * @param shardingFilter Sharding filter to use; {@link Filter#ALL} to not do sharding
-   * @param testIncludeFilterRegexp String denoting a regular expression with which
-   *     to filter tests.  Only test descriptions that match this regular
-   *     expression will be run.  If {@code null}, tests will not be filtered.
-   * @param testExcludeFilterRegexp String denoting a regular expression with which
-   *     to filter tests.  Only test descriptions that do not match this regular
-   *     expression will be run.  If {@code null}, tests will not be filtered.
-   * @return Filtered request (may be a request that delegates to
-   *         {@link ErrorReportingRunner}
+   * @param testIncludeFilterRegexp String denoting a regular expression with which to filter tests.
+   *     Only test descriptions that match this regular expression will be run. If {@code null},
+   *     tests will not be filtered.
+   * @param testExcludeFilterRegexp String denoting a regular expression with which to filter tests.
+   *     Only test descriptions that do not match this regular expression will be run. If {@code
+   *     null}, tests will not be filtered.
+   * @return Filtered request (may be a request that delegates to {@link ErrorReportingRunner}
    */
-  private static Request applyFilters(Request request, Filter shardingFilter,
-      @Nullable String testIncludeFilterRegexp, @Nullable String testExcludeFilterRegexp) {
+  private static Request applyFilters(
+      Request request,
+      Filter shardingFilter,
+      @Nullable String testIncludeFilterRegexp,
+      @Nullable String testExcludeFilterRegexp) {
     // Allow the user to specify a filter on the command line
     boolean allowNoTests = false;
     Filter filter = Filter.ALL;
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4RunnerModule.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4RunnerModule.java
index 63f14a9..abc337e 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4RunnerModule.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/junit4/JUnit4RunnerModule.java
@@ -33,7 +33,6 @@
 import java.util.HashSet;
 import java.util.Set;
 import java.util.function.Supplier;
-import javax.annotation.Nullable;
 import org.junit.runner.notification.RunListener;
 
 /** Utility class for real test runs. This is a legacy Dagger module. */
@@ -47,7 +46,7 @@
 
   @SuppressWarnings("CatchAndPrintStackTrace") // see comment below
   static OutputStream provideXmlStream(JUnit4Config config) {
-    @Nullable Path path = config.getXmlOutputPath();
+    Path path = config.getXmlOutputPath();
 
     if (path != null) {
       try {
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/AntXmlResultWriter.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/AntXmlResultWriter.java
index 8f7bfa5..69f3a05 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/AntXmlResultWriter.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/AntXmlResultWriter.java
@@ -20,7 +20,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
 
 /**
  * Writes the JUnit test nodes and their results into Ant-JUnit XML. Ant-JUnit XML is not a
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/BUILD b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/BUILD
index 1e3a798..a6a67fd 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/BUILD
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/BUILD
@@ -14,8 +14,7 @@
         "//src/java_tools/junitrunner/java/com/google/testing/junit/junit4:runner",
         "//src/java_tools/junitrunner/java/com/google/testing/junit/runner/sharding",
         "//src/java_tools/junitrunner/java/com/google/testing/junit/runner/util",
-        "//third_party/java/error_prone:annotations",
-        "//third_party/java/jsr305_annotations",
+        "//third_party/java/jspecify_annotations",
         "//third_party/java/junit:not-testonly",
     ],
 )
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/CanIgnoreReturnValue.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/CanIgnoreReturnValue.java
new file mode 100644
index 0000000..bc82987
--- /dev/null
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/CanIgnoreReturnValue.java
@@ -0,0 +1,25 @@
+// Copyright 2026 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.model;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(CLASS)
+@Target(METHOD)
+@interface CanIgnoreReturnValue {}
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestCaseNode.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestCaseNode.java
index 581dac6..fa32b28 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestCaseNode.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestCaseNode.java
@@ -32,7 +32,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ConcurrentMap;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
 import org.junit.runner.Description;
 
 /** A leaf in the test suite model. */
@@ -49,7 +49,7 @@
   private final Set<TestIntegration> integrations =
       Collections.newSetFromMap(new ConcurrentHashMap<TestIntegration, Boolean>());
 
-  @Nullable private volatile TestInterval runTimeInterval = null;
+  private volatile @Nullable TestInterval runTimeInterval = null;
   private volatile State state = State.INITIAL;
 
   TestCaseNode(Description description, TestSuiteNode parent) {
@@ -197,8 +197,7 @@
     return false;
   }
 
-  @Nullable
-  public TestInterval getRuntime() {
+  public @Nullable TestInterval getRuntime() {
     return runTimeInterval;
   }
 
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestNode.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestNode.java
index a7e842c..e70e2eb 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestNode.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestNode.java
@@ -16,7 +16,7 @@
 
 import com.google.testing.junit.runner.util.TestClock.TestInstant;
 import java.util.List;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
 import org.junit.runner.Description;
 
 /**
@@ -24,7 +24,7 @@
  */
 public abstract class TestNode {
   private final Description description;
-  @Nullable private TestResult result = null;
+  private @Nullable TestResult result = null;
 
   TestNode(Description description) {
     if (description == null) {
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestResult.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestResult.java
index 41d164b..7f2e45f 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestResult.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestResult.java
@@ -14,12 +14,11 @@
 
 package com.google.testing.junit.runner.model;
 
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
 import com.google.testing.junit.runner.util.TestIntegration;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
 
 /** Result of executing a test suite or test case. */
 public final class TestResult {
@@ -83,7 +82,7 @@
   private final String className;
   private final Map<String, String> properties;
   private final List<Throwable> failures;
-  @Nullable private final TestInterval runTime;
+  private final @Nullable TestInterval runTime;
   private final Set<TestIntegration> integrations;
   private final Status status;
   private final int numTests;
@@ -123,8 +122,7 @@
     return integrations;
   }
 
-  @Nullable
-  public TestInterval getRunTimeInterval() {
+  public @Nullable TestInterval getRunTimeInterval() {
     return runTime;
   }
 
@@ -160,7 +158,7 @@
     private String className = null;
     private Map<String, String> properties = null;
     private List<Throwable> failures = null;
-    @Nullable private TestInterval runTime = null;
+    private @Nullable TestInterval runTime = null;
     private Set<TestIntegration> integrations = null;
     private Status status = null;
     private Integer numTests = null;
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestSuiteModel.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestSuiteModel.java
index 8caf8e2..cde48d5 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestSuiteModel.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/model/TestSuiteModel.java
@@ -32,7 +32,7 @@
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
 import org.junit.runner.Description;
 import org.junit.runner.manipulation.Filter;
 
@@ -50,7 +50,7 @@
   private final TestClock testClock;
   private final AtomicBoolean wroteXml = new AtomicBoolean(false);
   private final XmlResultWriter xmlResultWriter;
-  @Nullable private final Filter shardingFilter;
+  private final @Nullable Filter shardingFilter;
 
   private TestSuiteModel(Builder builder) {
     rootNode = builder.rootNode;
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/BUILD b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/BUILD
index 2397af1..0f90f75 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/BUILD
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/BUILD
@@ -12,8 +12,7 @@
     srcs = glob(["*.java"]),
     visibility = ["//visibility:public"],
     deps = [
-        "//third_party/java/error_prone:annotations",
-        "//third_party/java/jsr305_annotations",
+        "//third_party/java/jspecify_annotations",
         "//third_party/java/junit:not-testonly",
     ],
 )
@@ -26,7 +25,7 @@
     ],
     visibility = ["//visibility:public"],
     deps = [
-        "//third_party/java/jsr305_annotations",
+        "//third_party/java/jspecify_annotations",
     ],
 )
 
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/CanIgnoreReturnValue.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/CanIgnoreReturnValue.java
new file mode 100644
index 0000000..de5009d
--- /dev/null
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/CanIgnoreReturnValue.java
@@ -0,0 +1,25 @@
+// Copyright 2026 The Bazel Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.testing.junit.runner.util;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(CLASS)
+@Target(METHOD)
+@interface CanIgnoreReturnValue {}
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/FakeTestClock.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/FakeTestClock.java
index 7cb4285..5005f42 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/FakeTestClock.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/FakeTestClock.java
@@ -14,7 +14,6 @@
 
 package com.google.testing.junit.runner.util;
 
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
 import java.time.Duration;
 import java.time.Instant;
 
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/SuiteUtil.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/SuiteUtil.java
index 1a39a65..f383cdd 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/SuiteUtil.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/SuiteUtil.java
@@ -18,7 +18,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
 
 /** Utility methods for inspecting and manipulating test suites. */
 @SuppressWarnings({"JdkImmutableCollections", "JdkCollectors"})
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/TestIntegration.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/TestIntegration.java
index 302d922..acd7075 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/TestIntegration.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/TestIntegration.java
@@ -14,7 +14,6 @@
 
 package com.google.testing.junit.runner.util;
 
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
 import java.util.EnumMap;
 import java.util.Map;
 
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/TestIntegrationsRunnerIntegration.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/TestIntegrationsRunnerIntegration.java
index 78a8894..f442a37 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/TestIntegrationsRunnerIntegration.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/TestIntegrationsRunnerIntegration.java
@@ -15,7 +15,7 @@
 package com.google.testing.junit.runner.util;
 
 import com.google.testing.junit.runner.util.TestIntegrationsExporter.Callback;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
 
 /** JUnit runner integration code for TestIntegration. */
 public class TestIntegrationsRunnerIntegration {
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/TestPropertyRunnerIntegration.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/TestPropertyRunnerIntegration.java
index b640def..9297142 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/TestPropertyRunnerIntegration.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/TestPropertyRunnerIntegration.java
@@ -15,8 +15,7 @@
 package com.google.testing.junit.runner.util;
 
 import com.google.testing.junit.runner.util.TestPropertyExporter.Callback;
-
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
 
 /**
  * JUnit runner integration code for test properties. Most code should not
diff --git a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/XmlEscapers.java b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/XmlEscapers.java
index edaaa22..e206abe 100644
--- a/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/XmlEscapers.java
+++ b/src/java_tools/junitrunner/java/com/google/testing/junit/runner/util/XmlEscapers.java
@@ -14,10 +14,9 @@
 
 package com.google.testing.junit.runner.util;
 
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
 import java.util.HashMap;
 import java.util.Map;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
 
 /**
  * Utility class for dealing with escaping XML content and attributes.
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/BUILD b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/BUILD
index fa1aec3..75c580e 100644
--- a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/BUILD
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/BUILD
@@ -32,8 +32,7 @@
         "//src/test/java/com/google/devtools/build/lib/testutil:TestUtils",
         "//third_party/java/guava:base",
         "//third_party/java/guava:collect",
-        "//third_party/java/guava:io",
-        "//third_party/java/jsr305_annotations",
+        "//third_party/java/jspecify_annotations",
         "//third_party/java/junit",
         "//third_party/java/mockito",
         "//third_party/java/truth",
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4BazelMock.java b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4BazelMock.java
index 52f769d..413facb 100644
--- a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4BazelMock.java
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4BazelMock.java
@@ -14,8 +14,6 @@
 
 package com.google.testing.junit.runner.junit4;
 
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
-
 public final class JUnit4BazelMock {
 
   public static Builder builder() {
diff --git a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4RunnerTest.java b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4RunnerTest.java
index 66cfb0d..d339e0e 100644
--- a/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4RunnerTest.java
+++ b/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/junit4/JUnit4RunnerTest.java
@@ -44,7 +44,7 @@
 import java.util.Properties;
 import java.util.Set;
 import java.util.function.Supplier;
-import javax.annotation.Nullable;
+import org.jspecify.annotations.Nullable;
 import org.junit.After;
 import org.junit.Test;
 import org.junit.internal.TextListener;
diff --git a/third_party/BUILD b/third_party/BUILD
index 7418ed5..a39f957 100644
--- a/third_party/BUILD
+++ b/third_party/BUILD
@@ -53,6 +53,7 @@
         "//third_party/java/jimfs:srcs",
         "//third_party/java/jmh:srcs",
         "//third_party/java/jol:srcs",
+        "//third_party/java/jspecify_annotations:srcs",
         "//third_party/java/jsr250_annotations:srcs",
         "//third_party/java/jsr305_annotations:srcs",
         "//third_party/java/jsr330_inject:srcs",
diff --git a/third_party/java/jspecify_annotations/BUILD b/third_party/java/jspecify_annotations/BUILD
new file mode 100644
index 0000000..3cf59f6
--- /dev/null
+++ b/third_party/java/jspecify_annotations/BUILD
@@ -0,0 +1,13 @@
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"])
+
+alias(
+    name = "jspecify_annotations",
+    actual = "@maven//:org_jspecify_jspecify",
+)
+
+filegroup(
+    name = "srcs",
+    srcs = glob(["**"]),
+)