Skip to content

Conversation

@pstreef
Copy link
Contributor

@pstreef pstreef commented Jan 5, 2026

Problem

Java's default InputStream.read(byte[], int, int) implementation calls the single-byte read() in a loop, causing up to 350x slower performance for bulk reads. Many InputStream subclasses only override the single-byte read() method but not the bulk read method.

Solution

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.

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.
@timtebeek timtebeek self-requested a review January 5, 2026 12:13
@timtebeek timtebeek added the recipe Recipe requested label Jan 5, 2026
Copy link
Member

@timtebeek timtebeek left a comment

Choose a reason for hiding this comment

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

Nice one! Should help folks and fix performance problems they might not even know they have.

For now we've not added this recipe to any larger composite, meaning folks would need to seek out and run this recipe specifically; shall we keep it that way?

@github-project-automation github-project-automation bot moved this from In Progress to Ready to Review in OpenRewrite Jan 5, 2026

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return Preconditions.check(new DeclaresType<>(JAVA_IO_INPUT_STREAM, true), new JavaIsoVisitor<ExecutionContext>() {
Copy link
Member

Choose a reason for hiding this comment

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

This required a small change upstream to allow the precondition to be used: openrewrite/rewrite@e91804a

@pstreef
Copy link
Contributor Author

pstreef commented Jan 7, 2026

For now we've not added this recipe to any larger composite, meaning folks would need to seek out and run this recipe specifically; shall we keep it that way?

I dont really know what the practice here has been in the past. What do you advise?

@timtebeek
Copy link
Member

I think it's fine to keep as is for now: especially since we can't automatically fix any case it might be best not to repeatedly warn about any such cases if folks decide not to follow up.

@timtebeek timtebeek merged commit b695463 into main Jan 7, 2026
2 checks passed
@timtebeek timtebeek deleted the feat/add-inputstream-bulk-read-recipe branch January 7, 2026 12:51
@github-project-automation github-project-automation bot moved this from Ready to Review to Done in OpenRewrite Jan 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

recipe Recipe requested

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants