-
Notifications
You must be signed in to change notification settings - Fork 135
Fix ConcurrentModificationExceptions thrown from BaselineNullAway #2427
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
Conversation
Generate changelog in
|
| private static boolean anyProjectUsesJava15(Project proj) { | ||
| return proj.getAllprojects().stream() | ||
| .anyMatch(project -> project.getTasks().withType(JavaCompile.class).stream() | ||
| .anyMatch(project -> ImmutableList.copyOf(project.getTasks().withType(JavaCompile.class)).stream() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we would be better off replacing the Collection.stream() here using something along these lines:
project.getTasks().withType(JavaCompile.class).matching(comp -> {
JavaVersion javaVersion = JavaVersion.toVersion(comp.getTargetCompatibility());
return javaVersion == JavaVersion.VERSION_15;
}).isEmpty()I suspect the TaskContainer may be a bit smarter about modification within iteration when it controls the iteration rather than returning a stream wrapping a spliterator, but it's difficult to say without a reliable reproducer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this by testing gw classes --stacktrace on my internal failing repo, and that command:
- fails on
com.palantir.baseline:gradle-baseline-java:4.180.0 - succeeds on
com.palantir.baseline:gradle-baseline-java:4.180.0-8-ga477298 - fails on
com.palantir.baseline:gradle-baseline-java:4.180.0-9-g05114a5
So I think the ImmutableList copy approach works and the TaskCollection one doesn't. At least it gets these runs to pass.
05114a5 to
a477298
Compare
carterkozak
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
|
Released 4.181.0 |
###### _excavator_ is a bot for automating changes across repositories. Changes produced by the roomba/latest-baseline-oss check. # Release Notes ## 4.181.0 | Type | Description | Link | | ---- | ----------- | ---- | | Fix | Fix ConcurrentModificationExceptions thrown from BaselineNullAway | palantir/gradle-baseline#2427 | To enable or disable this check, please contact the maintainers of Excavator.
Addresses #2413
Before this PR
java.util.ConcurrentModificationExceptionthrown from this plugin:After this PR
==COMMIT_MSG==
Fix ConcurrentModificationExceptions thrown from BaselineNullAway
==COMMIT_MSG==
Possible downsides?
I think this exception indicates that the project's task list is being modified/resolved at the same time as we iterate over it in this class.
By making a copy before iterating, I think we'll reduce the CMEs being thrown, but not actually fix the underlying issue of concurrent changes happening. I'm not super familiar with Gradle internals, but think we may instead need to do something where BaselineNullAway runs in a
doLastso it doesn't interfere with project resolution.This fix was confirmed on an internal failing repro, but we don't have a test case for it as part of this PR.
By using the TaskCollection's.anyMatch()directly, we hope that it is a bit smarter about modification during iteration versus converting to a Stream and usingStream#anyMatch().