Skip to content

Add recipe to add bulk read method to InputStream implementations#6383

Closed
pstreef wants to merge 4 commits intomainfrom
feat/add-inputstream-bulk-read-recipe
Closed

Add recipe to add bulk read method to InputStream implementations#6383
pstreef wants to merge 4 commits intomainfrom
feat/add-inputstream-bulk-read-recipe

Conversation

@pstreef
Copy link
Copy Markdown
Contributor

@pstreef pstreef commented Dec 5, 2025

Java's default InputStream.read(byte[], int, int) calls the single-byte read() in a loop, causing up to 350x slower performance for bulk reads.

This recipe detects InputStream subclasses that:

  • Override read() but not read(byte[], int, int)
  • Delegate to another InputStream

For simple delegation patterns, it adds the missing bulk read method. For complex bodies (side effects, transformations), it adds a search marker for manual review.

Handles both anonymous and named classes, ternary and if-statement null check styles, and skips FilterInputStream subclasses.

What's changed?

Adding a recipe to detect and update (simple cases of) InputStream implementations that are missing the bulk read method.

What's your motivation?

I found 3 such instances in OpenRewrite itself which caused huge performance gains when fixed.

Anything in particular you'd like reviewers to focus on?

Is this recipe useful in its current form, should it maybe only detect? or is only fixing simple cases good too?

Anyone you would like to review specifically?

@timtebeek

Have you considered any alternatives or workarounds?

Not creating this recipe

Any additional context

Checklist

  • I've added unit tests to cover both positive and negative cases
  • I've read and applied the recipe conventions and best practices
  • I've used the IntelliJ IDEA auto-formatter on affected files

@github-project-automation github-project-automation bot moved this to In Progress in OpenRewrite Dec 5, 2025
@pstreef pstreef force-pushed the feat/add-inputstream-bulk-read-recipe branch 2 times, most recently from 3112869 to 29d5b13 Compare December 5, 2025 11:49
@timtebeek timtebeek self-requested a review December 5, 2025 11:49
@pstreef pstreef force-pushed the feat/add-inputstream-bulk-read-recipe branch from 29d5b13 to 275752f Compare December 5, 2025 11:50
@pstreef pstreef force-pushed the feat/add-inputstream-bulk-read-recipe branch from 275752f to 265ca75 Compare December 5, 2025 12:09
Java's default InputStream.read(byte[], int, int) calls the single-byte
read() in a loop, causing up to 350x slower performance for bulk reads.

This recipe detects InputStream subclasses that:
- Override read() but not read(byte[], int, int)
- Delegate to another InputStream (including subclasses like ZipInputStream)

For simple delegation patterns, it adds the missing bulk read method.
For complex bodies (side effects, transformations), it adds a search
marker for manual review.

Handles both anonymous and named classes, ternary and if-statement
null check styles, and skips FilterInputStream subclasses.
@pstreef pstreef force-pushed the feat/add-inputstream-bulk-read-recipe branch from 265ca75 to cd815bb Compare December 5, 2025 12:12
- Extract duplicated visitor logic to processInputStreamClass()
- Use @value for AnalysisResult instead of manual constructor
- Import Set/HashSet instead of using FQN
- Rename test nested classes (Transform, NoChange, MarkForReview)
- Update copyright year to 2025
@pstreef pstreef marked this pull request as ready for review December 5, 2025 13:44
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openrewrite.java.cleanup;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This package only contains a few visitors at this moment, as we've moved the majority of the recipes that were formerly here into rewrite-static-analysis.

For this recipe I'm doubting on where to place it, but I feel perhaps https://github.com/openrewrite/rewrite-migrate-java/blob/b566417e5ef76dfa6b4026cb2c08b9a5b335cbe7/src/main/java/org/openrewrite/java/migrate/io is more fitting than having it here.

If we keep it here, it would also be included with any other language module as those tend to use rewrite-java, which feels a bit off.

pstreef added a commit to openrewrite/rewrite-migrate-java that referenced this pull request Jan 5, 2026
Adds a recipe to detect and fix InputStream subclasses that only override
the single-byte read() method. Java's default bulk read implementation
calls read() in a loop, which can cause up to 350x slower performance.

For simple delegation patterns, the recipe adds the missing bulk read
method. For complex bodies (side effects, transformations), it adds a
search marker for manual review.

Moved from openrewrite/rewrite#6383 per review feedback.
@pstreef
Copy link
Copy Markdown
Contributor Author

pstreef commented Jan 5, 2026

Moved to openrewrite/rewrite-migrate-java#961 per @timtebeek's review feedback.

@pstreef
Copy link
Copy Markdown
Contributor Author

pstreef commented Jan 5, 2026

Closing in favor of openrewrite/rewrite-migrate-java#961

@pstreef pstreef closed this Jan 5, 2026
@github-project-automation github-project-automation bot moved this from In Progress to Done in OpenRewrite Jan 5, 2026
@timtebeek timtebeek deleted the feat/add-inputstream-bulk-read-recipe branch January 5, 2026 12:12
timtebeek added a commit to openrewrite/rewrite-migrate-java that referenced this pull request Jan 7, 2026
* Add bulk read method to InputStream implementations

Adds a recipe to detect and fix InputStream subclasses that only override
the single-byte read() method. Java's default bulk read implementation
calls read() in a loop, which can cause up to 350x slower performance.

For simple delegation patterns, the recipe adds the missing bulk read
method. For complex bodies (side effects, transformations), it adds a
search marker for manual review.

Moved from openrewrite/rewrite#6383 per review feedback.

* Apply the first automated suggestions

* Add line to recipes.csv

* Apply formatter and further best practices

* Add placeholder for expanded precondition support upstream

* Add precondition and inline conditionals logic

---------

Co-authored-by: Tim te Beek <tim@moderne.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants