From 285b9dec5df06376763345fc3571474135c208ac Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Tue, 21 Jul 2026 16:25:00 -0700 Subject: [PATCH 1/8] WIP --- .../uber/nullaway/generics/JSpecifyJavacConfig.java | 7 ++++++- .../java/com/uber/nullaway/JSpecifyJDKModelsTest.java | 11 ++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/nullaway/src/main/java/com/uber/nullaway/generics/JSpecifyJavacConfig.java b/nullaway/src/main/java/com/uber/nullaway/generics/JSpecifyJavacConfig.java index a3a2d1094b..5116ed9332 100644 --- a/nullaway/src/main/java/com/uber/nullaway/generics/JSpecifyJavacConfig.java +++ b/nullaway/src/main/java/com/uber/nullaway/generics/JSpecifyJavacConfig.java @@ -20,9 +20,14 @@ public final class JSpecifyJavacConfig { public static final String ADD_TYPE_ANNOTATIONS_FLAG = "-XDaddTypeAnnotationsToSymbol=true"; public static final String HANDLE_WILDCARD_GENERICS_FLAG = "-XepOpt:NullAway:HandleWildcardGenerics=true"; + public static final String USE_JSPECIFY_JDK_MODELS = "-XepOpt:NullAway:JSpecifyJDKModels=true"; private static final List JSPECIFY_MODE_ARGS = - List.of(JSPECIFY_MODE_FLAG, ADD_TYPE_ANNOTATIONS_FLAG, HANDLE_WILDCARD_GENERICS_FLAG); + List.of( + JSPECIFY_MODE_FLAG, + ADD_TYPE_ANNOTATIONS_FLAG, + HANDLE_WILDCARD_GENERICS_FLAG, + USE_JSPECIFY_JDK_MODELS); private JSpecifyJavacConfig() {} diff --git a/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java b/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java index 5fe77cf758..1394d6f469 100644 --- a/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java +++ b/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java @@ -36,9 +36,7 @@ void use(Attributes attrs) { public void listContainingNullsWithModel() { makeTestHelperWithArgs( JSpecifyJavacConfig.withJSpecifyModeArgs( - List.of( - "-XepOpt:NullAway:AnnotatedPackages=foo", - "-XepOpt:NullAway:JSpecifyJDKModels=true"))) + List.of("-XepOpt:NullAway:AnnotatedPackages=foo"))) .addSourceLines( "Test.java", """ @@ -66,8 +64,11 @@ void testNonNullContents(List list) { @Test public void listContainingNullsWithoutModel() { makeTestHelperWithArgs( - JSpecifyJavacConfig.withJSpecifyModeArgs( - List.of("-XepOpt:NullAway:AnnotatedPackages=foo"))) + List.of( + "-XepOpt:NullAway:AnnotatedPackages=foo", + JSpecifyJavacConfig.JSPECIFY_MODE_FLAG, + JSpecifyJavacConfig.ADD_TYPE_ANNOTATIONS_FLAG, + JSpecifyJavacConfig.HANDLE_WILDCARD_GENERICS_FLAG)) .addSourceLines( "Test.java", """ From 1e3e2348a933e7a90891871a04bedbe22aaf5682 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Wed, 22 Jul 2026 17:22:38 -0700 Subject: [PATCH 2/8] test tweaks --- .../test/java/com/uber/nullaway/jspecify/GenericsTests.java | 6 +++++- .../nullaway/jspecify/StreamNullabilityPropagatorTests.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java b/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java index d693343c43..1046d328e7 100644 --- a/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java +++ b/nullaway/src/test/java/com/uber/nullaway/jspecify/GenericsTests.java @@ -2005,7 +2005,9 @@ public void testForNullTypeRhsTypeForArrayType() { class Test { static void testNegative() { List a = new ArrayList(); - Object[] o = a != null ? a.toArray() : null; + // TODO fix imprecise model of toArray() + // https://github.com/uber/NullAway/issues/1616 + @Nullable Object[] o = a != null ? a.toArray() : null; } } """) @@ -2582,6 +2584,8 @@ public class Test { static class K {} void foo(K<@Nullable Object> k) { K k2 = k; + // TODO should get no error here + // BUG: Diagnostic contains: returning @Nullable Supplier s = () -> null; } } diff --git a/nullaway/src/test/java/com/uber/nullaway/jspecify/StreamNullabilityPropagatorTests.java b/nullaway/src/test/java/com/uber/nullaway/jspecify/StreamNullabilityPropagatorTests.java index e02761b842..057d8ae58b 100644 --- a/nullaway/src/test/java/com/uber/nullaway/jspecify/StreamNullabilityPropagatorTests.java +++ b/nullaway/src/test/java/com/uber/nullaway/jspecify/StreamNullabilityPropagatorTests.java @@ -38,7 +38,7 @@ static Optional sumDoubles(@Nullable Double... doubles) { static Optional sumDoublesMissingfilter(@Nullable Double... doubles) { return Arrays.stream(doubles) - // BUG: Diagnostic contains: incompatible types + // BUG: Diagnostic contains: parameter a of referenced method is @NonNull .reduce(Double::sum); } From 05cd0f97ab52a03bf4e7112b2224abe8d894a039 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Wed, 22 Jul 2026 17:24:52 -0700 Subject: [PATCH 3/8] comment --- .../src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java b/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java index 1394d6f469..1142d6a8f5 100644 --- a/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java +++ b/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java @@ -64,6 +64,7 @@ void testNonNullContents(List list) { @Test public void listContainingNullsWithoutModel() { makeTestHelperWithArgs( + // We specifically exclude the JSpecifyJDKModels flag here List.of( "-XepOpt:NullAway:AnnotatedPackages=foo", JSpecifyJavacConfig.JSPECIFY_MODE_FLAG, From 224af3984026149d82dbe2d77394213e5d3ab7c6 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Wed, 22 Jul 2026 17:48:06 -0700 Subject: [PATCH 4/8] bug fix --- .../jdkannotations/JDKIntegrationTest.java | 9 +++++---- .../nullaway/handlers/LibraryModelsHandler.java | 2 +- .../com/uber/nullaway/handlers/StubxCacheUtil.java | 14 ++++++++------ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java b/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java index 9d7bb6584e..533052df49 100644 --- a/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java +++ b/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java @@ -83,10 +83,11 @@ static void testPositive() { public void libraryModelWithoutJarInferEnabledTest() { compilationHelper .setArgs( - Arrays.asList( - "-d", - temporaryFolder.getRoot().getAbsolutePath(), - "-XepOpt:NullAway:AnnotatedPackages=com.uber")) + JSpecifyJavacConfig.withJSpecifyModeArgs( + Arrays.asList( + "-d", + temporaryFolder.getRoot().getAbsolutePath(), + "-XepOpt:NullAway:AnnotatedPackages=com.uber"))) .addSourceLines( "Test.java", """ diff --git a/nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java b/nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java index 9a30555c8b..d095e79344 100644 --- a/nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java +++ b/nullaway/src/main/java/com/uber/nullaway/handlers/LibraryModelsHandler.java @@ -1657,7 +1657,7 @@ private static class ExternalStubxLibraryModels implements LibraryModels { ExternalStubxLibraryModels(boolean isJarInferEnabled, boolean isJSpecifyJDKEnabled) { String libraryModelLogName = "LM"; - StubxCacheUtil cacheUtil = new StubxCacheUtil(libraryModelLogName); + StubxCacheUtil cacheUtil = new StubxCacheUtil(libraryModelLogName, isJarInferEnabled); if (isJarInferEnabled) { // hardcoded loading of stubx files from android-jarinfer-models-sdkXX artifacts try (InputStream androidStubxIS = diff --git a/nullaway/src/main/java/com/uber/nullaway/handlers/StubxCacheUtil.java b/nullaway/src/main/java/com/uber/nullaway/handlers/StubxCacheUtil.java index fd10c80c90..c6565d20ba 100644 --- a/nullaway/src/main/java/com/uber/nullaway/handlers/StubxCacheUtil.java +++ b/nullaway/src/main/java/com/uber/nullaway/handlers/StubxCacheUtil.java @@ -80,21 +80,23 @@ private void LOG(boolean cond, String tag, String msg) { private final Map> nestedAnnotationInfoCache; /** - * Initializes a new {@code StubxCacheUtil} instance. - * - *

This sets up the caches for argument annotations and upper bounds, sets the log caller, and - * loads the stubx files. + * Initializes a new {@code StubxCacheUtil} instance, optionally loading JarInfer stubx files + * discovered on the classpath. * * @param logCaller Identifier for logging purposes. + * @param loadJarInferModels whether to load stubx files provided by {@link JarInferStubxProvider} + * implementations */ - public StubxCacheUtil(String logCaller) { + StubxCacheUtil(String logCaller, boolean loadJarInferModels) { argAnnotCache = new LinkedHashMap<>(); upperBoundCache = new HashMap<>(); nullMarkedClassesCache = new HashSet<>(); methodTypeParamNullableUpperBoundCache = HashMultimap.create(); nestedAnnotationInfoCache = new HashMap<>(); this.logCaller = logCaller; - loadStubxFiles(); + if (loadJarInferModels) { + loadStubxFiles(); + } } public Map getUpperBoundCache() { From 1faf001ba55c1cd957843dce2c65d7896bfd3456 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Thu, 23 Jul 2026 21:30:21 -0700 Subject: [PATCH 5/8] Update nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lázaro Clapp --- .../src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java b/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java index 1142d6a8f5..b48f0d92ec 100644 --- a/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java +++ b/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java @@ -64,7 +64,7 @@ void testNonNullContents(List list) { @Test public void listContainingNullsWithoutModel() { makeTestHelperWithArgs( - // We specifically exclude the JSpecifyJDKModels flag here + // We specifically exclude the JSpecifyJDKModels flag here (so we can't use `withJSpecifyModeArgs`) List.of( "-XepOpt:NullAway:AnnotatedPackages=foo", JSpecifyJavacConfig.JSPECIFY_MODE_FLAG, From 0e6a9c196c23b2411c912fce6d02b3c5a6494341 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Thu, 23 Jul 2026 21:31:35 -0700 Subject: [PATCH 6/8] review comment --- .../com/uber/nullaway/jdkannotations/JDKIntegrationTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java b/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java index 533052df49..1ab88b0588 100644 --- a/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java +++ b/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java @@ -83,6 +83,9 @@ static void testPositive() { public void libraryModelWithoutJarInferEnabledTest() { compilationHelper .setArgs( + // Run this test in JSpecify mode to ensure that loading of JDK models does not also + // load + // external astubx files from JarInfer JSpecifyJavacConfig.withJSpecifyModeArgs( Arrays.asList( "-d", From e8edea0bbf3fda36753ad59a5a2667d53c2f0bc6 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Thu, 23 Jul 2026 21:57:23 -0700 Subject: [PATCH 7/8] formatting --- .../src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java b/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java index b48f0d92ec..901d912a55 100644 --- a/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java +++ b/nullaway/src/test/java/com/uber/nullaway/JSpecifyJDKModelsTest.java @@ -64,7 +64,8 @@ void testNonNullContents(List list) { @Test public void listContainingNullsWithoutModel() { makeTestHelperWithArgs( - // We specifically exclude the JSpecifyJDKModels flag here (so we can't use `withJSpecifyModeArgs`) + // We specifically exclude the JSpecifyJDKModels flag here (so we can't use + // `withJSpecifyModeArgs`) List.of( "-XepOpt:NullAway:AnnotatedPackages=foo", JSpecifyJavacConfig.JSPECIFY_MODE_FLAG, From 90a73c0ea40bff4e1422e44210d86772b10dcb59 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Thu, 23 Jul 2026 21:58:56 -0700 Subject: [PATCH 8/8] formatting --- .../com/uber/nullaway/jdkannotations/JDKIntegrationTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java b/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java index 1ab88b0588..8588ec53c8 100644 --- a/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java +++ b/jdk-annotations/jdk-integration-test/src/test/java/com/uber/nullaway/jdkannotations/JDKIntegrationTest.java @@ -84,8 +84,7 @@ public void libraryModelWithoutJarInferEnabledTest() { compilationHelper .setArgs( // Run this test in JSpecify mode to ensure that loading of JDK models does not also - // load - // external astubx files from JarInfer + // load external astubx files from JarInfer JSpecifyJavacConfig.withJSpecifyModeArgs( Arrays.asList( "-d",