Problem
When using the OR precondition pattern with ScanningRecipes like ModuleHasDependency or RepositoryContainsFile, the recipes fail with a NullPointerException:
java.lang.NullPointerException: Cannot invoke "java.util.concurrent.atomic.AtomicBoolean.get()" because "acc" is null
at org.openrewrite.search.RepositoryContainsFile.getVisitor(RepositoryContainsFile.java:73)
at org.openrewrite.config.DeclarativeRecipe.orVisitors(DeclarativeRecipe.java:483)
Example
---
type: specs.openrewrite.org/v1beta/recipe
name: org.example.ProjectUsesJackson
description: OR precondition - matches if ANY condition is true
recipeList:
- org.openrewrite.java.dependencies.search.ModuleHasDependency:
groupIdPattern: com.fasterxml.jackson.core
artifactIdPattern: jackson-*
- org.openrewrite.search.RepositoryContainsFile:
filePattern: "**/jackson-config.json"
---
type: specs.openrewrite.org/v1beta/recipe
name: org.example.AddJacksonAnnotations
preconditions:
- org.example.ProjectUsesJackson
recipeList:
- org.openrewrite.java.dependencies.AddDependency:
groupId: com.fasterxml.jackson.core
artifactId: jackson-annotations
version: 2.x
Root Cause
In DeclarativeRecipe.getInitialValue(), only direct preconditions get their accumulators registered:
for (Recipe precondition : preconditions) {
if (precondition instanceof ScanningRecipe && isScanningRequired(precondition)) {
acc.recipeToAccumulator.put(precondition, ((ScanningRecipe<?>) precondition).getInitialValue(ctx));
}
}
When orVisitors() recurses into the nested ScanningRecipes in the wrapper recipe's recipeList, it tries to look them up:
conditions.add(scanning.getVisitor(accumulator.recipeToAccumulator.get(scanning)));
But since they were never registered, get(scanning) returns null.
Suggested Fix
getInitialValue() and getScanner() should recursively register and scan ScanningRecipes that are nested inside precondition recipes' recipeLists.
Problem
When using the OR precondition pattern with
ScanningRecipes likeModuleHasDependencyorRepositoryContainsFile, the recipes fail with aNullPointerException:Example
Root Cause
In
DeclarativeRecipe.getInitialValue(), only direct preconditions get their accumulators registered:When
orVisitors()recurses into the nestedScanningRecipes in the wrapper recipe'srecipeList, it tries to look them up:But since they were never registered,
get(scanning)returnsnull.Suggested Fix
getInitialValue()andgetScanner()should recursively register and scanScanningRecipes that are nested inside precondition recipes'recipeLists.