Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSpecify mode: number of types arguments mismatch #791

Closed
ben-manes opened this issue Jul 22, 2023 · 14 comments
Closed

JSpecify mode: number of types arguments mismatch #791

ben-manes opened this issue Jul 22, 2023 · 14 comments
Labels
jspecify Related to support for jspecify standard (see jspecify.dev)

Comments

@ben-manes
Copy link

ben-manes commented Jul 22, 2023

I tried enabling jspecify mode without using those annotations yet. It crashed with the following error, referring to this line of code. I enabled it in errorprone-caffeine-conventions.gradle.kts by adding isJSpecifyMode = true under the nullaway configuration block.

> Task :caffeine:compileJava FAILED
/Users/ben/projects/caffeine/caffeine/src/main/java/com/github/benmanes/caffeine/cache/Caffeine.java:918: error: An unhandled exception was thrown by the Error Prone static analysis plugin.
        ? new AsyncEvictionListener(castedListener)
        ^
     Please report this at https://github.com/google/error-prone/issues/new and include the following:

     error-prone version: 2.20.0
     BugPattern: NullAway
     Stack Trace:
     java.lang.RuntimeException: Number of types arguments in com.github.benmanes.caffeine.cache.RemovalListener does not match @org.checkerframework.checker.nullness.qual.Nullable com.github.benmanes.caffeine.cache.RemovalListener<K1,V1>
        at com.uber.nullaway.GenericsChecks.compareNullabilityAnnotations(GenericsChecks.java:312)
        at com.uber.nullaway.GenericsChecks.checkTypeParameterNullnessForConditionalExpression(GenericsChecks.java:439)
        at com.uber.nullaway.NullAway.matchConditionalExpression(NullAway.java:1491)
        at com.google.errorprone.scanner.ErrorProneScanner.processMatchers(ErrorProneScanner.java:449)
@msridhar
Copy link
Collaborator

Thanks for the report! My current mental goal for our JSpecify support is that (1) it doesn't crash on existing code and (2) as much as possible, it doesn't report false positive warnings on existing code, with (1) more important than (2). (Of course support is still pretty incomplete so we will miss warnings for some time to come.) We will look into this.

@ben-manes
Copy link
Author

Thanks @msridhar! No rush, just playing and agree with your goals.

I thought maybe narrowing the rawtype by being more explicit would help, but it just shifted the exception.

<K1 extends K, V1 extends V> @Nullable RemovalListener<K1, V1> getEvictionListener(
    boolean async) {
  @SuppressWarnings("unchecked")
  var castedListener = (RemovalListener<K1, V1>) evictionListener;
  if (async && (castedListener != null)) {
    @SuppressWarnings({"rawtypes", "unchecked"})
    RemovalListener<K1, V1> rawListener = new AsyncEvictionListener(castedListener);
    return rawListener;
  }
  return castedListener;
}
Caffeine.java:919: error: An unhandled exception was thrown by the Error Prone static analysis plugin.
RemovalListener<K1, V1> rawListener = new AsyncEvictionListener(castedListener);

Stack Trace:
java.lang.RuntimeException: Number of types arguments in com.github.benmanes.caffeine.cache.RemovalListener does not match com.github.benmanes.caffeine.cache.RemovalListener<K1,V1>

@msridhar
Copy link
Collaborator

Here is a self-contained reproducer for this issue:

import org.checkerframework.checker.nullness.qual.Nullable;
class Test {
  interface RemovalListener<K, V> {}
  static final class AsyncEvictionListener<K, V> implements RemovalListener<K, V> {
    AsyncEvictionListener(RemovalListener<K, V> delegate) {}
  }
  static class Caffeine<K, V> {
    @Nullable RemovalListener<? super K, ? super V> evictionListener;
    @SuppressWarnings({"rawtypes", "unchecked"})
    <K1 extends K, V1 extends V> @Nullable RemovalListener<K1, V1> getEvictionListener(
        boolean async) {
      var castedListener = (RemovalListener<K1, V1>) evictionListener;
      return async && (castedListener != null)
          ? new AsyncEvictionListener(castedListener)
          : castedListener;
    }
  }
}

The issue indeed a raw type, for the expression new AsyncEvictionListener(castedListener). We have not tested much with raw types before, so in retrospect I'm not surprised it's causing a crash. We should detect and bail out of checking for this case.

If I use the diamond operator and write new AsyncEvictionListener<>(castedListener) I don't see a crash anymore on the small reproducer. Does this remove the crash in Caffeine as well @ben-manes? (Not at all urgent to check.) We also do not yet support inference for diamond operators, but at least there we have an explicit check for use of diamond and bail out.

Interestingly if I write new AsyncEvictionListener<K1,V1>(castedListener) I again get a crash; this is a manifestation of a variant of #740, which we are working on.

@msridhar msridhar added the jspecify Related to support for jspecify standard (see jspecify.dev) label Jul 25, 2023
@ben-manes
Copy link
Author

ben-manes commented Jul 25, 2023

The raw types are used to mask the incompatible generic types, so if adding those type arguments it results in a compilation error. The reason is that the cache pivots from storing the user's V value directly to instead CompletableFuture<V>, depending on if Caffeine.build or Caffeine.buildAsync were called. The same core classes are used with async adapters to coerce to the desired behavior, e.g. AsyncEvictionListener joins the future and calls the user's EvictionListener. Perhaps there is a better way, but (thanks to erasures) at the time using rawtypes seemed like a quick and elegant way to share most of the code.

@cpovirk
Copy link

cpovirk commented Jul 25, 2023

(On the rare occasions that we've had trouble with raw types for one reason or another, I've generally been able to either cast directly to the needed type or cast to Foo<?, ?> and then to the Foo<...> type I actually want. I haven't looked closely enough to see if either of those would work here. I think I've mostly defaulting to using raw types where I can get away with it, too :))

@ben-manes
Copy link
Author

If I try replacing the rawtypes with an unchecked cast this works around the issue, but also fails later on with a new bug:
class com.sun.tools.javac.code.Type$TypeVar$1 cannot be cast to class com.sun.tools.javac.code.Type$ClassType

Java changes
@SuppressWarnings("unchecked")
<K1 extends K, V1 extends V> @Nullable RemovalListener<K1, V1> getEvictionListener(
    boolean async) {
  var castedListener = (RemovalListener<K1, V1>) evictionListener;
  return async && (castedListener != null)
      ? (RemovalListener<K1, V1>) new AsyncEvictionListener<>(castedListener)
      : castedListener;
}

@SuppressWarnings("unchecked")
@Nullable <K1 extends K, V1 extends V> RemovalListener<K1, V1> getRemovalListener(boolean async) {
  RemovalListener<K1, V1> castedListener = (RemovalListener<K1, V1>) removalListener;
  return async && (castedListener != null)
      ? (RemovalListener<K1, V1>) new AsyncRemovalListener<>(castedListener, getExecutor())
      : castedListener;
}
Exception
> Task :caffeine:compileJava FAILED
/Users/ben/projects/caffeine/caffeine/src/main/java/com/github/benmanes/caffeine/cache/Caffeine.java:1164: error: An unhandled exception was thrown by the Error Prone static analysis plugin.
        ? new BoundedLocalCache.BoundedLocalAsyncLoadingCache<K1, V1>(self, loader)
        ^
     Please report this at https://github.com/google/error-prone/issues/new and include the following:

     error-prone version: 2.20.0
     BugPattern: NullAway
     Stack Trace:
     java.lang.ClassCastException: class com.sun.tools.javac.code.Type$TypeVar$1 cannot be cast to class com.sun.tools.javac.code.Type$ClassType (com.sun.tools.javac.code.Type$TypeVar$1 and com.sun.tools.javac.code.Type$ClassType are in module jdk.compiler of loader 'app')
        at com.uber.nullaway.GenericsChecks.typeWithPreservedAnnotations(GenericsChecks.java:401)
        at com.uber.nullaway.GenericsChecks.getTreeType(GenericsChecks.java:215)
        at com.uber.nullaway.GenericsChecks.checkTypeParameterNullnessForConditionalExpression(GenericsChecks.java:432)
        at com.uber.nullaway.NullAway.matchConditionalExpression(NullAway.java:1491)
        at com.google.errorprone.scanner.ErrorProneScanner.processMatchers(ErrorProneScanner.java:449)
        at com.google.errorprone.scanner.ErrorProneScanner.visitConditionalExpression(ErrorProneScanner.java:578)
        at com.google.errorprone.scanner.ErrorProneScanner.visitConditionalExpression(ErrorProneScanner.java:150)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCConditional.accept(JCTree.java:1413)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitReturn(TreeScanner.java:469)
        at com.google.errorprone.scanner.ErrorProneScanner.visitReturn(ErrorProneScanner.java:817)
        at com.google.errorprone.scanner.ErrorProneScanner.visitReturn(ErrorProneScanner.java:150)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1570)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
        at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:90)
        at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:105)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitBlock(TreeScanner.java:248)
        at com.google.errorprone.scanner.ErrorProneScanner.visitBlock(ErrorProneScanner.java:520)
        at com.google.errorprone.scanner.ErrorProneScanner.visitBlock(ErrorProneScanner.java:150)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1048)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
        at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:90)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitMethod(TreeScanner.java:206)
        at com.google.errorprone.scanner.ErrorProneScanner.visitMethod(ErrorProneScanner.java:740)
        at com.google.errorprone.scanner.ErrorProneScanner.visitMethod(ErrorProneScanner.java:150)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:898)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
        at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:90)
        at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:105)
        at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:113)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitClass(TreeScanner.java:187)
        at com.google.errorprone.scanner.ErrorProneScanner.visitClass(ErrorProneScanner.java:548)
        at com.google.errorprone.scanner.ErrorProneScanner.visitClass(ErrorProneScanner.java:150)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:808)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
        at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:105)
        at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:113)
        at jdk.compiler/com.sun.source.util.TreeScanner.visitCompilationUnit(TreeScanner.java:144)
        at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:560)
        at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:150)
        at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:591)
        at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:56)
        at com.google.errorprone.scanner.Scanner.scan(Scanner.java:58)
        at com.google.errorprone.scanner.ErrorProneScannerTransformer.apply(ErrorProneScannerTransformer.java:43)
        at com.google.errorprone.ErrorProneAnalyzer.finished(ErrorProneAnalyzer.java:156)
        at jdk.compiler/com.sun.tools.javac.api.MultiTaskListener.finished(MultiTaskListener.java:132)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1418)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1365)
        at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:960)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.handleExceptions(JavacTaskImpl.java:147)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100)
        at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94)
        at org.gradle.internal.compiler.java.IncrementalCompileTask.call(IncrementalCompileTask.java:92)

@msridhar
Copy link
Collaborator

Thanks again for investigating! Yeah I think this crash with the unchecked cast is also what I was seeing when I added type variables, and it's related to #740 and the fixes we are doing there. We will test that fix with this example for sure to make sure the ClassCastException goes away.

msridhar added a commit that referenced this issue Jul 26, 2023
We check for the presence of a raw type and (for now) bail out of any
checking. Adding further support for JSpecify checking of raw types is a
low priority (not even sure anything needs to be done).

This fixes the initial crash from #791, though we may want to leave that
issue open for now until we split off issues for the other crashes as
needed.
@msridhar
Copy link
Collaborator

msridhar commented Nov 8, 2023

@ben-manes FYI we've fixed a few crasher issues with our JSpecify mode code now (including #856 which is only on the master branch). If you get a chance to try this out again on Caffeine, let us know if you are still seeing crashes, or if we can close this issue. Thanks!

@ben-manes
Copy link
Author

ben-manes commented Nov 9, 2023

@msridhar I enabled it as described against master (902c14d) and received the following error,

$ gradle compileTestJava --console plain
...
> Task :caffeine:compileJavaPoetJava
/Users/ben/projects/caffeine/caffeine/src/javaPoet/java/com/github/benmanes/caffeine/cache/NodeFactoryGenerator.java:153: error: An unhandled exception was thrown by the Error Prone static analysis plugin.
    features.add((Feature) combination.get(0));
            ^
     Please report this at https://github.com/google/error-prone/issues/new and include the following:

     error-prone version: 2.23.0
     BugPattern: NullAway
     Stack Trace:
     com.google.common.util.concurrent.UncheckedExecutionException: java.lang.NullPointerException: castToNonNull failed!
  	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2086)
  	at com.google.common.cache.LocalCache.get(LocalCache.java:4012)
  	at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:4035)
  	at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:5013)
  	at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:5020)
  	at com.uber.nullaway.dataflow.DataFlow.dataflow(DataFlow.java:157)
  	at com.uber.nullaway.dataflow.DataFlow.resultFor(DataFlow.java:290)
  	at com.uber.nullaway.dataflow.DataFlow.resultForExpr(DataFlow.java:266)
  	at com.uber.nullaway.dataflow.DataFlow.expressionDataflow(DataFlow.java:208)
  	at com.uber.nullaway.dataflow.AccessPathNullnessAnalysis.getNullness(AccessPathNullnessAnalysis.java:131)
  	at com.uber.nullaway.NullAway.nullnessFromDataflow(NullAway.java:2415)
  	at com.uber.nullaway.NullAway.mayBeNullExpr(NullAway.java:2393)
  	at com.uber.nullaway.NullAway.matchDereference(NullAway.java:2442)
  	at com.uber.nullaway.NullAway.matchMemberSelect(NullAway.java:548)
  	at com.google.errorprone.scanner.ErrorProneScanner.processMatchers(ErrorProneScanner.java:449)
...
  Caused by: java.lang.NullPointerException: castToNonNull failed!
  	at com.uber.nullaway.NullabilityUtil.castToNonNull(NullabilityUtil.java:409)
  	at com.uber.nullaway.GenericsChecks.getGenericReturnNullnessAtInvocation(GenericsChecks.java:791)
  	at com.uber.nullaway.dataflow.AccessPathNullnessPropagation.genericReturnIsNullable(AccessPathNullnessPropagation.java:1031)
  	at com.uber.nullaway.dataflow.AccessPathNullnessPropagation.returnValueNullness(AccessPathNullnessPropagation.java:1008)
  	at com.uber.nullaway.dataflow.AccessPathNullnessPropagation.visitMethodInvocation(AccessPathNullnessPropagation.java:924)
  	at com.uber.nullaway.dataflow.AccessPathNullnessPropagation.visitMethodInvocation(AccessPathNullnessPropagation.java:139)
  	at org.checkerframework.nullaway.dataflow.cfg.node.MethodInvocationNode.accept(MethodInvocationNode.java:122)
  	at org.checkerframework.nullaway.dataflow.analysis.AbstractAnalysis.callTransferFunction(AbstractAnalysis.java:349)
  	at org.checkerframework.nullaway.dataflow.analysis.ForwardAnalysisImpl.callTransferFunction(ForwardAnalysisImpl.java:377)
  	at org.checkerframework.nullaway.dataflow.analysis.ForwardAnalysisImpl.performAnalysisBlock(ForwardAnalysisImpl.java:151)
  	at org.checkerframework.nullaway.dataflow.analysis.ForwardAnalysisImpl.performAnalysis(ForwardAnalysisImpl.java:105)
  	at com.uber.nullaway.dataflow.DataFlow$1.load(DataFlow.java:93)
  	at com.uber.nullaway.dataflow.DataFlow$1.load(DataFlow.java:85)
  	at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3571)
  	at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2313)
  	at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2190)
  	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2080)
  	... 249 more

@ben-manes
Copy link
Author

I tried the snapshot jar and it failed with the same error at a later task (jspecify.patch).

patch
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index cf40d57e..4fe374f5 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -65,7 +65,7 @@ kotlin = "1.9.20"
 lincheck = "2.18.1"
 mockito = "5.7.0"
 nexus-publish = "2.0.0-rc-1"
-nullaway-core = "0.10.16"
+nullaway-core = "0.10.17-SNAPSHOT"
 nullaway-plugin = "1.6.0"
 ohc = "0.6.1"
 okhttp = "4.12.0"
diff --git a/gradle/plugins/settings.gradle.kts b/gradle/plugins/settings.gradle.kts
index 029760cd..d7c99137 100644
--- a/gradle/plugins/settings.gradle.kts
+++ b/gradle/plugins/settings.gradle.kts
@@ -8,6 +8,7 @@ dependencyResolutionManagement {
   repositories {
     gradlePluginPortal()
     mavenCentral()
+    maven(url = "https://oss.sonatype.org/content/repositories/snapshots/")
   }
   versionCatalogs {
     create("libs") {
diff --git a/gradle/plugins/src/main/kotlin/quality/errorprone-caffeine-conventions.gradle.kts b/gradle/plugins/src/main/kotlin/quality/errorprone-caffeine-conventions.gradle.kts
index ea900282..73dead75 100644
--- a/gradle/plugins/src/main/kotlin/quality/errorprone-caffeine-conventions.gradle.kts
+++ b/gradle/plugins/src/main/kotlin/quality/errorprone-caffeine-conventions.gradle.kts
@@ -70,6 +70,7 @@ tasks.withType<JavaCompile>().configureEach {
       annotatedPackages.add("com.google.common")
       checkOptionalEmptiness = true
       suggestSuppressions = true
+      isJSpecifyMode = true
       checkContracts = true
     }
   }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 87c9d7c6..6ec70f34 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -10,6 +10,7 @@ plugins {
 dependencyResolutionManagement {
   repositories {
     mavenCentral()
+    maven(url = "https://oss.sonatype.org/content/repositories/snapshots/")
   }
 }
error
$ gradle clean compileTestJava --console plain --no-build-cache
Configuration on demand is an incubating feature.
Calculating task graph as no configuration cache is available for tasks: clean compileTestJava
> Task :plugins:generateExternalPluginSpecBuilders UP-TO-DATE
> Task :plugins:extractPrecompiledScriptPluginPlugins UP-TO-DATE
> Task :plugins:compilePluginsBlocks UP-TO-DATE
> Task :plugins:generatePrecompiledScriptPluginAccessors UP-TO-DATE
> Task :plugins:generateScriptPluginAdapters UP-TO-DATE
> Task :plugins:compileKotlin UP-TO-DATE
> Task :plugins:compileJava NO-SOURCE
> Task :plugins:pluginDescriptors UP-TO-DATE
> Task :plugins:processResources UP-TO-DATE
> Task :plugins:classes UP-TO-DATE
> Task :plugins:jar UP-TO-DATE
> Task :jcache:clean
> Task :guava:clean
> Task :guava:processResources NO-SOURCE
> Task :clean
> Task :compileJava NO-SOURCE
> Task :processResources NO-SOURCE
> Task :classes UP-TO-DATE
> Task :compileTestJava NO-SOURCE
> Task :jcache:processResources
> Task :guava:downloadCaffeine
> Task :simulator:clean
> Task :jcache:downloadCaffeine
> Task :simulator:downloadCaffeine
> Task :caffeine:clean
> Task :caffeine:processResources NO-SOURCE
> Task :caffeine:processCodeGenResources NO-SOURCE
> Task :caffeine:processJavaPoetResources
> Task :caffeine:downloadCaffeine
> Task :simulator:processResources
> Task :caffeine:compileJavaPoetJava
> Task :caffeine:javaPoetClasses
> Task :caffeine:generateNodes
> Task :caffeine:generateLocalCaches
> Task :caffeine:compileJava
> Task :caffeine:classes

> Task :jcache:compileJava FAILED
/Users/ben/projects/caffeine/jcache/src/main/java/com/github/benmanes/caffeine/jcache/CacheFactory.java:92: error: An unhandled exception was thrown by the Error Prone static analysis plugin.
    CaffeineConfiguration<K, V> config = resolveConfigurationFor(cacheManager, configuration);
                                                                ^
     Please report this at https://github.com/google/error-prone/issues/new and include the following:

     error-prone version: 2.23.0
     BugPattern: NullAway
     Stack Trace:
     com.google.common.util.concurrent.UncheckedExecutionException: java.lang.NullPointerException: castToNonNull failed!
  	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2086)
  	at com.google.common.cache.LocalCache.get(LocalCache.java:4012)
  	at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:4035)
  	at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:5013)
  	at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:5020)
  	at com.uber.nullaway.dataflow.DataFlow.dataflow(DataFlow.java:157)
  	at com.uber.nullaway.dataflow.DataFlow.resultFor(DataFlow.java:290)
  	at com.uber.nullaway.dataflow.DataFlow.resultForExpr(DataFlow.java:266)
  	at com.uber.nullaway.dataflow.DataFlow.expressionDataflow(DataFlow.java:208)
  	at com.uber.nullaway.dataflow.AccessPathNullnessAnalysis.getNullness(AccessPathNullnessAnalysis.java:131)
  	at com.uber.nullaway.NullAway.nullnessFromDataflow(NullAway.java:2415)
  	at com.uber.nullaway.NullAway.mayBeNullExpr(NullAway.java:2393)
  	at com.uber.nullaway.NullAway.handleInvocation(NullAway.java:1741)
  	at com.uber.nullaway.NullAway.matchMethodInvocation(NullAway.java:407)
  	at com.google.errorprone.scanner.ErrorProneScanner.processMatchers(ErrorProneScanner.java:449)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitMethodInvocation(ErrorProneScanner.java:746)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitMethodInvocation(ErrorProneScanner.java:150)
  	at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1666)
  	at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:90)
  	at jdk.compiler/com.sun.source.util.TreeScanner.visitVariable(TreeScanner.java:223)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitVariable(ErrorProneScanner.java:885)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitVariable(ErrorProneScanner.java:150)
  	at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:990)
  	at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:105)
  	at jdk.compiler/com.sun.source.util.TreeScanner.visitBlock(TreeScanner.java:248)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitBlock(ErrorProneScanner.java:520)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitBlock(ErrorProneScanner.java:150)
  	at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1048)
  	at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:90)
  	at jdk.compiler/com.sun.source.util.TreeScanner.visitMethod(TreeScanner.java:206)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitMethod(ErrorProneScanner.java:740)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitMethod(ErrorProneScanner.java:150)
  	at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:898)
  	at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:90)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:105)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:113)
  	at jdk.compiler/com.sun.source.util.TreeScanner.visitClass(TreeScanner.java:187)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitClass(ErrorProneScanner.java:548)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitClass(ErrorProneScanner.java:150)
  	at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:808)
  	at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:82)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:74)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:48)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scan(TreeScanner.java:105)
  	at jdk.compiler/com.sun.source.util.TreeScanner.scanAndReduce(TreeScanner.java:113)
  	at jdk.compiler/com.sun.source.util.TreeScanner.visitCompilationUnit(TreeScanner.java:144)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:560)
  	at com.google.errorprone.scanner.ErrorProneScanner.visitCompilationUnit(ErrorProneScanner.java:150)
  	at jdk.compiler/com.sun.tools.javac.tree.JCTree$JCCompilationUnit.accept(JCTree.java:591)
  	at jdk.compiler/com.sun.source.util.TreePathScanner.scan(TreePathScanner.java:56)
  	at com.google.errorprone.scanner.Scanner.scan(Scanner.java:58)
  	at com.google.errorprone.scanner.ErrorProneScannerTransformer.apply(ErrorProneScannerTransformer.java:43)
  	at com.google.errorprone.ErrorProneAnalyzer.finished(ErrorProneAnalyzer.java:156)
  	at jdk.compiler/com.sun.tools.javac.api.MultiTaskListener.finished(MultiTaskListener.java:132)
  	at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1418)
  	at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1365)
  	at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:960)
  	at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)
  	at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.handleExceptions(JavacTaskImpl.java:147)
  	at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100)
  	at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94)
  	at org.gradle.internal.compiler.java.IncrementalCompileTask.call(IncrementalCompileTask.java:92)
  	at org.gradle.api.internal.tasks.compile.AnnotationProcessingCompileTask.call(AnnotationProcessingCompileTask.java:94)
  	at org.gradle.api.internal.tasks.compile.ResourceCleaningCompilationTask.call(ResourceCleaningCompilationTask.java:57)
  	at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:55)
  	at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:39)
  	at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.delegateAndHandleErrors(NormalizingJavaCompiler.java:98)
  	at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:52)
  	at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:38)
  	at org.gradle.api.internal.tasks.compile.AnnotationProcessorDiscoveringCompiler.execute(AnnotationProcessorDiscoveringCompiler.java:51)
  	at org.gradle.api.internal.tasks.compile.AnnotationProcessorDiscoveringCompiler.execute(AnnotationProcessorDiscoveringCompiler.java:37)
  	at org.gradle.api.internal.tasks.compile.ModuleApplicationNameWritingCompiler.execute(ModuleApplicationNameWritingCompiler.java:46)
  	at org.gradle.api.internal.tasks.compile.ModuleApplicationNameWritingCompiler.execute(ModuleApplicationNameWritingCompiler.java:36)
  	at org.gradle.jvm.toolchain.internal.DefaultToolchainJavaCompiler.execute(DefaultToolchainJavaCompiler.java:57)
  	at org.gradle.api.tasks.compile.JavaCompile.lambda$createToolchainCompiler$3(JavaCompile.java:202)
  	at org.gradle.api.internal.tasks.compile.CleaningJavaCompiler.execute(CleaningJavaCompiler.java:53)
  	at org.gradle.api.internal.tasks.compile.incremental.IncrementalCompilerFactory.lambda$createRebuildAllCompiler$0(IncrementalCompilerFactory.java:52)
  	at org.gradle.api.internal.tasks.compile.incremental.SelectiveCompiler.execute(SelectiveCompiler.java:70)
  	at org.gradle.api.internal.tasks.compile.incremental.SelectiveCompiler.execute(SelectiveCompiler.java:44)
  	at org.gradle.api.internal.tasks.compile.incremental.IncrementalResultStoringCompiler.execute(IncrementalResultStoringCompiler.java:66)
  	at org.gradle.api.internal.tasks.compile.incremental.IncrementalResultStoringCompiler.execute(IncrementalResultStoringCompiler.java:52)
  	at org.gradle.api.internal.tasks.compile.CompileJavaBuildOperationReportingCompiler$1.call(CompileJavaBuildOperationReportingCompiler.java:64)
  	at org.gradle.api.internal.tasks.compile.CompileJavaBuildOperationReportingCompiler$1.call(CompileJavaBuildOperationReportingCompiler.java:48)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
  	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:78)
  	at org.gradle.api.internal.tasks.compile.CompileJavaBuildOperationReportingCompiler.execute(CompileJavaBuildOperationReportingCompiler.java:48)
  	at org.gradle.api.tasks.compile.JavaCompile.performCompilation(JavaCompile.java:220)
  	at org.gradle.api.tasks.compile.JavaCompile.performIncrementalCompilation(JavaCompile.java:161)
  	at org.gradle.api.tasks.compile.JavaCompile.compile(JavaCompile.java:146)
  	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
  	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:125)
  	at org.gradle.api.internal.project.taskfactory.IncrementalTaskAction.doExecute(IncrementalTaskAction.java:45)
  	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:51)
  	at org.gradle.api.internal.project.taskfactory.IncrementalTaskAction.execute(IncrementalTaskAction.java:26)
  	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:29)
  	at org.gradle.api.internal.tasks.execution.TaskExecution$3.run(TaskExecution.java:248)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
  	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:73)
  	at org.gradle.api.internal.tasks.execution.TaskExecution.executeAction(TaskExecution.java:233)
  	at org.gradle.api.internal.tasks.execution.TaskExecution.executeActions(TaskExecution.java:216)
  	at org.gradle.api.internal.tasks.execution.TaskExecution.executeWithPreviousOutputFiles(TaskExecution.java:199)
  	at org.gradle.api.internal.tasks.execution.TaskExecution.execute(TaskExecution.java:166)
  	at org.gradle.internal.execution.steps.ExecuteStep.executeInternal(ExecuteStep.java:105)
  	at org.gradle.internal.execution.steps.ExecuteStep.access$000(ExecuteStep.java:44)
  	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:59)
  	at org.gradle.internal.execution.steps.ExecuteStep$1.call(ExecuteStep.java:56)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
  	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:78)
  	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:56)
  	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:44)
  	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:67)
  	at org.gradle.internal.execution.steps.RemovePreviousOutputsStep.execute(RemovePreviousOutputsStep.java:37)
  	at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:41)
  	at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:74)
  	at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:55)
  	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:50)
  	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:28)
  	at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.executeDelegateBroadcastingChanges(CaptureStateAfterExecutionStep.java:100)
  	at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:72)
  	at org.gradle.internal.execution.steps.CaptureStateAfterExecutionStep.execute(CaptureStateAfterExecutionStep.java:50)
  	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:40)
  	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:29)
  	at org.gradle.internal.execution.steps.BuildCacheStep.executeWithoutCache(BuildCacheStep.java:179)
  	at org.gradle.internal.execution.steps.BuildCacheStep.lambda$execute$1(BuildCacheStep.java:70)
  	at org.gradle.internal.Either$Right.fold(Either.java:175)
  	at org.gradle.internal.execution.caching.CachingState.fold(CachingState.java:59)
  	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:68)
  	at org.gradle.internal.execution.steps.BuildCacheStep.execute(BuildCacheStep.java:46)
  	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:36)
  	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:25)
  	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:36)
  	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:22)
  	at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:91)
  	at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$2(SkipUpToDateStep.java:55)
  	at java.base/java.util.Optional.orElseGet(Optional.java:369)
  	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:55)
  	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:37)
  	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:65)
  	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:36)
  	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:37)
  	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:27)
  	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:77)
  	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:38)
  	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:108)
  	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:55)
  	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:71)
  	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:45)
  	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.executeWithNonEmptySources(SkipEmptyWorkStep.java:177)
  	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:86)
  	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:53)
  	at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:32)
  	at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:21)
  	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
  	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:36)
  	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:23)
  	at org.gradle.internal.execution.steps.CleanupStaleOutputsStep.execute(CleanupStaleOutputsStep.java:75)
  	at org.gradle.internal.execution.steps.CleanupStaleOutputsStep.execute(CleanupStaleOutputsStep.java:41)
  	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.lambda$execute$2(ExecuteWorkBuildOperationFiringStep.java:66)
  	at java.base/java.util.Optional.orElseGet(Optional.java:369)
  	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.execute(ExecuteWorkBuildOperationFiringStep.java:66)
  	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.execute(ExecuteWorkBuildOperationFiringStep.java:38)
  	at org.gradle.internal.execution.steps.AssignWorkspaceStep.lambda$execute$0(AssignWorkspaceStep.java:32)
  	at org.gradle.api.internal.tasks.execution.TaskExecution$4.withWorkspace(TaskExecution.java:293)
  	at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:30)
  	at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:21)
  	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:37)
  	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:27)
  	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:47)
  	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:34)
  	at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:64)
  	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:145)
  	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:134)
  	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
  	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
  	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
  	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74)
  	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
  	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
  	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
  	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
  	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
  	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:78)
  	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
  	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42)
  	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:331)
  	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:318)
  	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.lambda$execute$0(DefaultTaskExecutionGraph.java:314)
  	at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:80)
  	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:314)
  	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:303)
  	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:463)
  	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:380)
  	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
  	at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
  	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
  	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
  	at java.base/java.lang.Thread.run(Thread.java:829)
  Caused by: java.lang.NullPointerException: castToNonNull failed!
  	at com.uber.nullaway.NullabilityUtil.castToNonNull(NullabilityUtil.java:409)
  	at com.uber.nullaway.GenericsChecks.getGenericReturnNullnessAtInvocation(GenericsChecks.java:791)
  	at com.uber.nullaway.dataflow.AccessPathNullnessPropagation.genericReturnIsNullable(AccessPathNullnessPropagation.java:1031)
  	at com.uber.nullaway.dataflow.AccessPathNullnessPropagation.returnValueNullness(AccessPathNullnessPropagation.java:1008)
  	at com.uber.nullaway.dataflow.AccessPathNullnessPropagation.visitMethodInvocation(AccessPathNullnessPropagation.java:924)
  	at com.uber.nullaway.dataflow.AccessPathNullnessPropagation.visitMethodInvocation(AccessPathNullnessPropagation.java:139)
  	at org.checkerframework.nullaway.dataflow.cfg.node.MethodInvocationNode.accept(MethodInvocationNode.java:122)
  	at org.checkerframework.nullaway.dataflow.analysis.AbstractAnalysis.callTransferFunction(AbstractAnalysis.java:349)
  	at org.checkerframework.nullaway.dataflow.analysis.ForwardAnalysisImpl.callTransferFunction(ForwardAnalysisImpl.java:377)
  	at org.checkerframework.nullaway.dataflow.analysis.ForwardAnalysisImpl.performAnalysisBlock(ForwardAnalysisImpl.java:151)
  	at org.checkerframework.nullaway.dataflow.analysis.ForwardAnalysisImpl.performAnalysis(ForwardAnalysisImpl.java:105)
  	at com.uber.nullaway.dataflow.DataFlow$1.load(DataFlow.java:93)
  	at com.uber.nullaway.dataflow.DataFlow$1.load(DataFlow.java:85)
  	at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3571)
  	at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2313)
  	at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2190)
  	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2080)
  	... 235 more
1 error

@msridhar
Copy link
Collaborator

msridhar commented Nov 9, 2023

Thank you @ben-manes! We can reproduce this problem now. @akulk022 will be looking into fixing the problems and we should be able to rebuild ourselves with snapshots to see if there are new issues. Will update here once we've fixed all the crashes 🙂

msridhar added a commit that referenced this issue Nov 13, 2023
…method caller (#858)

In reference to the
[exception](#791 (comment))
mentioned in the discussion for #791 .

Adding the test case to reproduce the same issue:

```java
class Test {
    static class B<T>{
        String build(){return "x";}
    }
    static String testNegative() {
        //We were getting the aforementioned mentioned exception when we tried to do this
        return new B<>().build();
    }
}
```
All unit tests have passed for the changes that were made for this.

---------

Co-authored-by: Manu Sridharan <[email protected]>
@akulk022
Copy link
Collaborator

akulk022 commented Nov 13, 2023

@ben-manes We were able to resolve the previous issue and I tried rebuilding on the latest snapshot version and there were no further issues. Can you confirm this once? Thanks!

@ben-manes
Copy link
Author

worked for me! I'll try a few of the jspecify annotations later on, but this is a great milestone. thanks!

@msridhar
Copy link
Collaborator

worked for me! I'll try a few of the jspecify annotations later on, but this is a great milestone. thanks!

@ben-manes sounds great, we'd love to get your feedback! To set expectations, we are still missing support for many JSpecify features, and some may be important for usage in practice. We don't have a way to get relevant annotations (in particular type variable upper bounds) into unannotated third-party libraries or the JDK yet, so, e.g., we aren't yet able to support proper checking for a type like java.util.function.Function<@Nullable Object, @Nullable Object>, or writing @Nullable on a generic type argument to a collection in java.util. We also don't yet have any support for generic methods, so we can't check calls to methods like Collections.sort where nullability of the arguments should be consistent. Also no support yet for wildcards or nullability of array elements.

And finally, we have been almost entirely focused on checking usages of generic classes, but not on checking the implementation of the generic class itself, which could be a big limitation for Caffeine.

Anyway, if / when you have time, if you have any suggestions on how to prioritize these features, we'd be happy to hear them 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
jspecify Related to support for jspecify standard (see jspecify.dev)
Projects
None yet
Development

No branches or pull requests

4 participants