Skip to content

Add synchronization around use of JDT code formatter to prevent NPE/race condition #6079

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

Merged
merged 2 commits into from
May 2, 2025

Conversation

alextwoods
Copy link
Contributor

Add synchronization around use of JDT code formatter to prevent NPE/race condition.

Motivation and Context

Occasionally a NullPointerException (NPE) is raised during code generation with stack traces point to
the JavaCodeFormatte#L93r. The NPE is happening deep in the eclipse JDT code (in the scanner created by the DefaultCodeFormatter).

It appears there is a race condition in the org.eclipse.jdt.internal.formatter.DefaultCodeFormatter in the probeFormatting method (see the stack trace). The decompiled .class file has this code (simplified to highlight issue):

public class DefaultCodeFormatter extends CodeFormatter {
  private static Scanner PROBING_SCANNER;  // NOTE: static

  private TextEdit probeFormatting(String source, int indentationLevel, String lineSeparator, IRegion[] regions, boolean includeComments) {
    if (PROBING_SCANNER == null) {
        PROBING_SCANNER = new Scanner(true, false, false, 3276800L, 3276800L, (char[][])null, (char[][])null, true);
    }
    PROBING_SCANNER.setSource(source.toCharArray());
    // .... Do work [skipping for brevity], calling `PROBING_SCANNER.getNextToken()` many times.
    PROBING_SCANNER.setSource((char[])null); // Cleanup at the end - Sets the source to null
  }
}

Since the PROBING_SCANNER is static and shared across all instances of the class, its possible for one thread to complete the work and call setSource(null) while another thread is in the working section and trying to call getNextToken(), which will fail with the NPE we are seeing in stack traces with the message: Cannot load from char array because "this.source" is null.

We currently depend on org.eclipse.jdt.core at 3.10.0 which is ~10 years old, but we cannot easily upgrade this dependency - newer versions of the library require later versions of the JDK.


## Modifications
Adds a synchronization block around the use of the JDT code formatter.  This should prevent multiple threads for executing the problematic block of code above concurrently. Manual benchmarking has shown no performance degradation from adding this synchronization.

NOTE: The lock Object MUST be a static/class level object to ensure that all usages of the formatter are synchronized. 

## Testing
Manual testing of class build with many threads to reproduce the issue + re-running test with synchronization fix. 

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)

## Checklist
<!--- Go over all the following points, and put an `x` in all the boxes that apply -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
- [x] I have read the [CONTRIBUTING](https://github.com/aws/aws-sdk-java-v2/blob/master/CONTRIBUTING.md) document
- [x] Local run of `mvn install` succeeds
- [x] My code follows the code style of this project
- [ ] My change requires a change to the Javadoc documentation
- [ ] I have updated the Javadoc documentation accordingly
- [ ] I have added tests to cover my changes
- [x] All new and existing tests passed
- [x] I have added a changelog entry. Adding a new entry must be accomplished by running the `scripts/new-change` script and following the instructions. Commit the new file created by the script in `.changes/next-release` with your changes.
- [ ] My change is to implement 1.11 parity feature and I have updated [LaunchChangelog](https://github.com/aws/aws-sdk-java-v2/blob/master/docs/LaunchChangelog.md)

## License
<!--- The SDK is released under the Apache 2.0 license (http://aws.amazon.com/apache2.0/), so any code you submit will be released under that license -->
<!--- For substantial contributions, we may ask you to sign a Contributor License Agreement (http://en.wikipedia.org/wiki/Contributor_License_Agreement) -->
<!--- Put an `x` in the below box if you confirm that this request can be released under the Apache 2 license -->
- [x] I confirm that this pull request can be released under the Apache 2 license

@alextwoods alextwoods requested a review from a team as a code owner April 30, 2025 20:47
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
55.3% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@alextwoods alextwoods added this pull request to the merge queue May 1, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 1, 2025
@alextwoods alextwoods added this pull request to the merge queue May 1, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 1, 2025
@alextwoods alextwoods added this pull request to the merge queue May 1, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 1, 2025
@alextwoods alextwoods added this pull request to the merge queue May 1, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to no response for status checks May 1, 2025
@alextwoods alextwoods added this pull request to the merge queue May 1, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 1, 2025
@alextwoods alextwoods added this pull request to the merge queue May 2, 2025
Merged via the queue into master with commit 21b4a51 May 2, 2025
38 of 39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants