Visitar URL original
Add nonFilteredFiles glob exclusions and opt-in gracefulBinaryHandling by gnodet · Pull Request #395 · apache/maven-filtering · GitHub
Skip to content

Add nonFilteredFiles glob exclusions and opt-in gracefulBinaryHandling - #395

Merged
gnodet merged 6 commits into
apache:masterfrom
gnodet:fix/394-non-filtered-files-glob
Sep 24, 2026
Merged

gnodet merged 6 commits into
apache:masterfrom
gnodet:fix/394-non-filtered-files-glob

Conversation

@gnodet

@gnodet gnodet commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds two complementary mechanisms for handling binary files in filtered resource directories, replacing the silent-fallback approach from #303.
Fixes #394.

Changes

1. Per-resource nonFilteredFiles glob list (primary mechanism)

Resource now has a nonFilteredFiles: List<String> field accepting Ant-style glob patterns. Files matching any pattern are copied as-is, bypassing the filter chain — even within a <resource> block that has <filtering>true</filtering>.

DefaultMavenResourcesFiltering evaluates these patterns (via SelectorUtils.matchPath(), already on the classpath) alongside the existing filteredFileExtension() check.

Advantages over extension-only matching:

  • Handles extension-less binaries (test keystores, generated fixtures)
  • Supports path-scoped exclusions (**/certs/**, **/keys/**)
  • Is per-resource, so surgical — does not affect other resource blocks

Example (exposed by maven-resources-plugin in a companion PR):

<resource>
  <directory>src/main/resources</directory>
  <filtering>true</filtering>
  <nonFilteredFiles>
    <nonFilteredFile>**/*.p12</nonFilteredFile>
    <nonFilteredFile>**/*.jks</nonFilteredFile>
    <nonFilteredFile>**/certs/**</nonFilteredFile>
    <nonFilteredFile>binary-file</nonFilteredFile>
  </nonFilteredFiles>
</resource>

2. Opt-in gracefulBinaryHandling flag (safety net)

MavenResourcesExecution now has a gracefulBinaryHandling boolean (default false). When enabled, MalformedInputException during filtering causes a WARN log and a direct Files.copy() fallback instead of a build failure.

  • Opt-in (default false) — encoding errors are not silently swallowed by default
  • Always warns — the user is told filtering was skipped and what to do
  • Falls back to direct Files.copy(), not a recursive method call

This flag is propagated through MavenResourcesExecution.copyOf().

Tests

  • DefaultMavenResourcesFilteringTest: 4 new unit tests for matchesNonFilteredGlob() (null/empty, extension glob, directory glob, exact name)
  • DefaultMavenResourcesFilteringTest: 2 integration tests using a mixed binary+properties resource directory — one for the glob mechanism, one for graceful fallback
  • Binary test fixtures added under src/test/units-files/binary-file/

See also

@gnodet
gnodet marked this pull request as ready for review September 24, 2026 13:01

@gnodet-bot gnodet-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review

Two issues, one correctness gap and one defensive-copy miss.

1. is silently dropped on two legacy API paths

calls the 5-arg overload which hardwires :

// DefaultMavenFileFilter.java ~line 73
public void copyFile(MavenFileFilterRequest mavenFileFilterRequest) throws MavenFilteringException {
    List<FilterWrapper> filterWrappers = getDefaultFilterWrappers(mavenFileFilterRequest);
    copyFile(                                   // ← 5-arg: gracefulBinaryHandling = false
            mavenFileFilterRequest.getFrom(),
            mavenFileFilterRequest.getTo(),
            mavenFileFilterRequest.isFiltering(),
            filterWrappers,
            mavenFileFilterRequest.getEncoding());
}

Same problem in the 8-arg overload — it also terminates at the 5-arg variant. Any caller that goes through either of those entry points cannot opt into graceful binary handling, regardless of what they pass. The feature silently does nothing for them.

needs a field (getter + setter), and both overloads must route through the 6-arg variant. Without this, the API surface the PR introduces is incomplete — the 6-arg is useful only if called directly; any higher-level entry point ignores it.

This review was generated by an AI agent, Hermès on behalf of @gnodet.

@gnodet

gnodet commented Sep 24, 2026

Copy link
Copy Markdown
Contributor Author

Fixed in 75627b9:

  1. gracefulBinaryHandling silently dropped on legacy paths — Added gracefulBinaryHandling field (getter + setter) to MavenFileFilterRequest. Updated copyFile(MavenFileFilterRequest) to route through the 6-arg variant, passing mavenFileFilterRequest.isGracefulBinaryHandling() instead of hardwiring false.

  2. Mutable collection returned from Resource.getNonFilteredFiles() — Now returns Collections.unmodifiableList(nonFilteredFiles) (or null if unset).

@gnodet

gnodet commented Sep 24, 2026

Copy link
Copy Markdown
Contributor Author

Both issues from the review addressed in 75627b9:

  1. gracefulBinaryHandling silently dropped on legacy API paths — Added gracefulBinaryHandling field (getter + setter) to MavenFileFilterRequest; the copyFile(MavenFileFilterRequest) overload now routes to the 6-arg variant and passes the flag through.
  2. Mutable collection returned directly — getNonFilteredFiles() now returns Collections.unmodifiableList(nonFilteredFiles) when non-null.

@gnodet
gnodet dismissed gnodet-bot’s stale review September 24, 2026 14:02

All issues addressed in 75627b9: gracefulBinaryHandling added to MavenFileFilterRequest and propagated through copyFile(MavenFileFilterRequest); getNonFilteredFiles() returns unmodifiable list.

@gnodet-bot gnodet-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Re-review after 75627b9

Both prior findings are addressed.

1. gracefulBinaryHandling silently dropped on legacy paths ✅ Fixed
MavenFileFilterRequest now has gracefulBinaryHandling (getter + setter). copyFile(MavenFileFilterRequest) routes through the 6-arg variant, passing mavenFileFilterRequest.isGracefulBinaryHandling() instead of hardwiring false.

2. Mutable collection in Resource.getNonFilteredFiles() ✅ Fixed
Now returns Collections.unmodifiableList(nonFilteredFiles) when non-null.

Pre-fix test validation: All 6 new tests fail to compile without the production changes (missing matchesNonFilteredGlob, setNonFilteredFiles, setGracefulBinaryHandling symbols) — confirming they are tightly bound to the fix.

SelectorUtils.matchPath(..., false) — passing isCaseSensitive=false is correct: case-insensitive glob matching works across case-sensitive (Linux) and case-insensitive (Windows) file systems without surprises.

Solid. Ready to merge.

This review was generated by an AI agent, Hermès on behalf of @gnodet.

@gnodet gnodet added the enhancement New feature or request label Sep 24, 2026
@gnodet

gnodet commented Sep 24, 2026

Copy link
Copy Markdown
Contributor Author

Fixes #394. Supersedes #303 (closed in favour of this approach). The maven-resources-plugin companion PR that exposes these features as plugin config is at apache/maven-resources-plugin#521 (TODO: update once that PR is open).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Unresolved API compatibility and glob-matching issues, plus documentation and test gaps.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 2 Medium severity · 1 Low severity

Open (4)
What changed in this PR

Adds per-resource glob exclusions and opt-in graceful handling for malformed binary resources.

Changes:

  • Adds Resource.nonFilteredFiles Ant-style glob support.
  • Adds and propagates gracefulBinaryHandling with warning-based fallback copying.
  • Adds binary fixtures and glob/fallback tests.
File Review
src/​test/​units-files/​binary-file/​app.properties No findings.
src/​test/​java/​org/​apache/​maven/​shared/​filtering/​DefaultMavenResourcesFilteringTest.java No findings.
src/​main/​java/​org/​apache/​maven/​shared/​filtering/​Resource.java No findings.
src/​main/​java/​org/​apache/​maven/​shared/​filtering/​MavenResourcesExecution.java Nit (3 votes): Update the getter description to reflect warning logging. Nit (1 vote): Test gracefulBinaryHandling propagation through copyOf().
src/​main/​java/​org/​apache/​maven/​shared/​filtering/​MavenFileFilterRequest.java No findings.
src/​main/​java/​org/​apache/​maven/​shared/​filtering/​MavenFileFilter.java Critical (4 votes): Make the new API backward-compatible, such as by using a default method delegating to the existing overload.
src/​main/​java/​org/​apache/​maven/​shared/​filtering/​DefaultMavenResourcesFiltering.java Moderate (3 votes): Record only actually filtered properties files for the encoding notice. Moderate (2 votes): Pass true to SelectorUtils.matchPath to preserve case-sensitive matching.
src/​main/​java/​org/​apache/​maven/​shared/​filtering/​DefaultMavenFileFilter.java No findings.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

Address the fallback permission preservation and mutable-list issues; add the requested propagation and API coverage tests.

Review effort: Lite
Findings: None

Resolved since last review (4)
Previously missed (1)

In code that hasn't changed since last review

Low severity Test gracefulBinaryHandling propagation in copyOf()

src/​main/​java/​org/​apache/​maven/​shared/​filtering/​MavenResourcesExecution.java:464

The new copyOf() propagation is part of the public behavior described by this change, but the existing MavenResourcesExecutionTest does not set or assert gracefulBinaryHandling. A future copy-field regression would therefore go unnoticed; add this flag to the copy-preservation test (including both enabled value and default false if desired).

@gnodet-bot gnodet-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Re-review after 1219140

All four Copilot findings addressed. Still solid.

1. MavenFileFilter.copyFile backward-compat ✅ Fixed
The 6-arg overload is now a default method delegating to the 5-arg overload. Existing MavenFileFilter implementations outside this module compile as-is and get gracefulBinaryHandling=false by default. DefaultMavenFileFilter retains its full override.

2. propertiesFiles tracking correctness ✅ Fixed
The guard now reads resource.isFiltering() && filteredExt && filteredGlob && isPropertiesFile(source), so a .properties file excluded by a nonFilteredFiles glob no longer appears in the end-of-run encoding notice.

3. Case-sensitivity choice documented and intentional ✅ Confirmed
SelectorUtils.matchPath(..., false) (case-insensitive) is consistent with the existing filteredFileExtension path (getExtension uses .toLowerCase(Locale.ROOT)). Making glob matching case-sensitive while extension matching is case-insensitive would create a surprising asymmetry. The decision is sound.

4. Getter Javadoc accuracy ✅ Fixed
Getter now says "copied as-is with a WARN log entry" — no longer "silently".

One minor gap remaining: copyOf() propagation test

MavenResourcesExecutionTest covers flatten, propertiesEncoding, delimiters, and interpolatorCustomizer propagation through copyOf(), but not gracefulBinaryHandling. A regression there would go unnoticed. Low risk since the field is one line in copyOf(), but easy to add:

@Test
void copyOfShouldPreserveGracefulBinaryHandling() {
    MavenResourcesExecution original = new MavenResourcesExecution();
    original.setGracefulBinaryHandling(true);
    MavenResourcesExecution copy = original.copyOf();
    assertTrue(copy.isGracefulBinaryHandling());
}

Not a blocker — the implementation is correct, CI is green across all platforms (JDK 17/21/25, Linux/macOS/Windows). The feature is well-designed: the glob mechanism is surgical and per-resource; the graceful fallback is opt-in and always warns. Ready to merge.

This review was generated by an AI agent, Hermès on behalf of @gnodet.

gnodet and others added 5 commits September 24, 2026 16:44
…he#394)

Resource now accepts a list of Ant-style glob patterns (nonFilteredFiles)
that are copied as-is even when the resource block has filtering enabled.
This covers extension-less binaries, path-scoped exclusions (**\/certs\/**),
and any pattern not expressible through the existing nonFilteredFileExtensions.

MavenResourcesExecution gains a gracefulBinaryHandling flag (default false).
When enabled, MalformedInputException during filtering triggers a WARN log
and a direct Files.copy() fallback rather than a build failure.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
… defensive copy in Resource.getNonFilteredFiles()
@gnodet
gnodet force-pushed the fix/394-non-filtered-files-glob branch from a8a4a6f to 6dac0c8 Compare September 24, 2026 16:45
@gnodet
gnodet merged commit 4e1b81d into apache:master Sep 24, 2026
8 of 11 checks passed
@github-actions github-actions Bot added this to the 4.0.0-beta-2 milestone Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add per-resource glob exclusions (nonFilteredFiles) and opt-in graceful binary fallback

4 participants