Skip to content

[IO-754] Preserve wildcard File overrides in FileUtils traversal - #893

Open
sushu0 wants to merge 4 commits into
apache:masterfrom
sushu0:codex/io-754-wildcard-file-override
Open

sushu0 wants to merge 4 commits into
apache:masterfrom
sushu0:codex/io-754-wildcard-file-override

Conversation

@sushu0

@sushu0 sushu0 commented Oct 19, 2026 •

Copy link
Copy Markdown

Fix IO-754: File-based traversal must honor an existing WildcardFileFilter.accept(File) override without making the superclass Path implementation call back into that override.

The earlier Path-to-File bridge caused a cycle when a File override delegated to super.accept(Path, BasicFileAttributes). That bridge has been removed. WildcardFileFilter has no runtime changes relative to current master.

The compatibility dispatch now happens at FileUtils traversal setup, before its file/directory AND/OR combinations:

  • Adapt a wildcard subclass's File override only when it inherits the base wildcard Path implementation. Explicit Path overrides retain their existing priority and receive the original BasicFileAttributes.
  • Adapt affected children in stock AND, OR and NOT combinations while preserving their order and short-circuiting. Custom composite subclasses retain their own Path behavior.
  • Preserve directory-root short-circuiting, avoid duplicate callbacks, and keep direct Path matching on Jimfs, null and root paths unchanged. Override inspection happens during traversal setup rather than for each file.

Master 308cfd2 was incorporated with merge commit c2331ba; the revision is commit 98a9ac3. The published branch history was retained through a normal merge and push.

Validation on Windows / Zulu OpenJDK 21.0.12.1 / Maven 3.9.16:

  • The upstream testAcceptFileOverrideDelegatingToSuperPath() regression fails with StackOverflowError using the pre-revision runtime after the master merge (c2331ba).
  • Pristine master 308cfd2, with only the final regression tests added, runs 25 tests with 8 failures and no errors or skips. Those failures cover the original acceptance/rejection problem, the delegated File entry points, directory filtering, and composed filters. The same 25 pass with this revision.
  • mvn -Dtest=FileUtilsListFilesTest,WildcardFileFilterTest,FilenameUtilsWildcardTest,AndFileFilterTest,OrFileFilterTest,FileFilterTest test checkstyle:check spotbugs:check passes all 106 related tests, with no failures, errors or skips, 0 Checkstyle violations, and 0 SpotBugs bug instances.
  • mvn -U pmd:check passes after routing dependency resolution through the existing local proxy.

The commands use a task-local Maven settings file. The complete default build was not rerun locally for this revision. Earlier local full-suite results were for 318b0c8 against 08ea7bf; earlier green hosted checks were for c7edc2d. Neither is presented as validation of the current revision. The default-build checklist item remains unchecked pending current-head evidence.

AI disclosure: OpenAI Codex assisted the investigation, implementation, regression tests, conflict resolution, validation and PR text. New commits use the repository's Assisted-By: OpenAI Codex trailer; earlier provenance trailers are preserved. No independent human review is claimed.

  • Read the contribution guidelines for this project.
  • Read the ASF Generative Tooling Guidance.
  • I used AI to create any part of, or all of, this pull request; the tool and extent are disclosed above.
  • Run a successful build using the default Maven goal.
  • Write regression tests that fail without the runtime change.
  • Write a description explaining what, how, and why.
  • Use meaningful commit messages containing the Jira issue key.

Delegate named default-file-system paths to accept(File), preserving
subclass filtering after the switch to NIO traversal. Keep direct name
matching for other file systems and for null or root paths.

Add regressions for File and Path overrides, real file iteration,
non-default file systems, and paths without a file name.

Generated-by: OpenAI Codex
Resolve the additive WildcardFileFilterTest conflict by keeping the
upstream repeated-wildcard regression and the File override regressions.
The contribution remains three files and 85 additions against master.

On upstream f9de7a4 the two focused suites run 15 tests with the same two
regression failures. The merged fix passes 28 related tests and Checkstyle.

Generated-by: OpenAI Codex
@sushu0
sushu0 marked this pull request as ready for review October 20, 2026 02:45
Copilot AI balanced review requested due to automatic review settings October 20, 2026 02:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@garydgregory
garydgregory marked this pull request as draft October 27, 2026 11:01
@garydgregory

garydgregory commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

The issue reported in IO-754 is real, and this PR fixes its example. However, forwarding WildcardFileFilter.accept(Path, BasicFileAttributes) to the virtual accept(File) method introduces another compatibility regression.

An existing subclass can delegate its File implementation to the superclass’s Path implementation:

final WildcardFileFilter filter = new WildcardFileFilter("*.txt") {
    private static final long serialVersionUID = 1L;

    @Override
    public boolean accept(final File file) {
        return super.accept(file.toPath(), null) == FileVisitResult.CONTINUE;
    }
};

filter.accept(new File("log.txt"));

Before this change, the call returns true. With the PR applied, it throws StackOverflowError: the superclass Path implementation calls the subclass File override, which calls the superclass Path implementation again.

I reproduced this behavior before and after applying the proposed runtime change. The new tests cover File overrides that delegate to super.accept(File, String), but do not cover delegation to super.accept(Path, BasicFileAttributes).

Please add this regression case and reconsider where the compatibility dispatch belongs. Fixing FileUtils traversal should preserve existing subclass delegation patterns as well as restore the behavior described in IO-754.

I've set this PR to draft. Please rebase on git master and see WildcardFileFilterTest.testAcceptFileOverrideDelegatingToSuperPath()

garydgregory added a commit that referenced this pull request Oct 27, 2026
Verify that a subclass's accept(File) override can delegate to
super.accept(Path, BasicFileAttributes). The test passes on the base
of PR #893 and throws StackOverflowError with its proposed IO-754 fix.
Keep the upstream File-to-super-Path regression and the original PR
regressions while updating to master 308cfd2 without rewriting history.
The newly added delegation test reproduces StackOverflowError with the
existing PR runtime change; the following fix relocates the dispatch.

Assisted-By: OpenAI Codex
…daries

Keep WildcardFileFilter's Path entry point independent so a File override
can safely delegate to super.accept(Path, BasicFileAttributes).

Adapt legacy File overrides during FileUtils traversal setup, before the
internal file/directory combinations. Preserve explicit Path overrides and
stock AND, OR and NOT combinations without duplicating callbacks. Leave
custom composite Path implementations intact and retain root short-circuit
ordering and path attributes.

The upstream recursion regression fails with StackOverflowError before
this revision. Upstream 308cfd2 with the final regressions runs 25 tests
with 8 failures; the revised runtime passes 106 related tests, Checkstyle,
SpotBugs and PMD. No unrelated full-suite rerun was performed.

Assisted-By: OpenAI Codex
@sushu0 sushu0 changed the title [IO-754] Honor WildcardFileFilter File overrides during Path traversal [IO-754] Preserve wildcard File overrides in FileUtils traversal Oct 27, 2026
@sushu0
sushu0 marked this pull request as ready for review October 27, 2026 15:11
@sushu0

sushu0 commented Oct 27, 2026

Copy link
Copy Markdown
Author

AI-generated update (OpenAI Codex), posted for @sushu0.

You're right: the File-to-super-Path delegation test reproduces StackOverflowError with the previous runtime change after merging master (c2331ba). The Path-to-File bridge has been removed; WildcardFileFilter now has no runtime diff against master.

The revised dispatch is at the FileUtils traversal boundary, before the internal file AND / directory-root OR combinations. It adapts a wildcard File override only when the subclass inherits the base Path implementation. Explicit Path overrides retain priority and their original attributes. Stock AND, OR and NOT combinations are adapted without changing their evaluation order; custom composite Path implementations are retained. Tests also check directory-root short-circuiting, single callbacks, File overrides delegating to each superclass overload, and unchanged Jimfs/null/root Path behavior.

Master 308cfd2 was incorporated through merge commit c2331ba, followed by fix 98a9ac3. This updates the branch without rewriting its published history; the push was a normal fast-forward.

Validation on JDK 21:

  • Pristine 308cfd2 plus the final regressions: 25 tests, 8 failures, no errors/skips. The same 25 pass with the revised runtime.
  • The expanded six-suite run passes all 106 tests, with no failures/errors/skips: mvn -Dtest=FileUtilsListFilesTest,WildcardFileFilterTest,FilenameUtilsWildcardTest,AndFileFilterTest,OrFileFilterTest,FileFilterTest test checkstyle:check spotbugs:check.
  • Checkstyle: 0 violations. SpotBugs: 0 bug instances. A separate mvn -U pmd:check passes.

The PR description now reflects this implementation and validation. The full local default build was not repeated, and its checklist item remains unchecked. Earlier full-suite and green CI results are explicitly scoped to their earlier revisions.

The PR is ready for re-review. Java CI for the new head is awaiting maintainer approval and has no jobs yet; no current-head hosted test success is claimed.

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.

3 participants