Repository navigation
Introduce TempFileService and lifecycle cleanup participant - #11405
arturobernalg wants to merge 1 commit into
Conversation
|
It looks like a duplicate of #11389 ? |
Yes. one for master and the other for maven-4.X |
| * System property to keep temp material for diagnostics. | ||
| * | ||
| */ | ||
| public static final String KEEP_PROP = "maven.tempfile.keep"; |
There was a problem hiding this comment.
Rename to MAVEN_TEMPFILE_KEEP for consistency.
gnodet
left a comment
There was a problem hiding this comment.
Review: Introduce TempFileService and lifecycle cleanup participant
The concept is sound — providing a managed temp file service with automatic cleanup at session end is a useful addition. However, there are several API design issues that should be addressed before merging into the Maven 4 API.
High
@Nonnull on void return methods — TempFileService.register() and cleanup() have @Nonnull on their void return type. This is semantically meaningless — void methods have no return value to be null or non-null. Other services (e.g., ArtifactManager.setPath()) do not annotate void returns with @Nonnull. Remove @Nonnull from these two methods and instead annotate the parameters.
Medium
-
KEEP_PROPnaming convention (Constants.java) — Every other constant inConstants.javauses theMAVEN_prefix (113 occurrences). The new constant should follow suit:MAVEN_TEMPFILE_KEEPinstead ofKEEP_PROP. -
Missing
@Experimentalannotation (TempFileService.java) — Every otherServiceinterface inorg.apache.maven.api.servicescarries@Experimental(ArtifactResolver,ArtifactManager,Interpolator, etc.). This should too. -
Boolean.getBoolean(KEEP_PROP)reads JVM system property (DefaultTempFileService.java) —Boolean.getBoolean()only checksSystem.getProperty(), so the property cannot be set viapom.xml<properties>, profiles, orsettings.xml. Consider usingsession.getUserProperties()orsession.getSystemProperties()if this should be settable through Maven's property resolution. If this is intentionally a JVM-level diagnostic flag, that's fine — just document the rationale. -
Missing
@sinceand@Config(Constants.java) — All recent constant additions have@since 4.1.0and a@Configannotation (e.g.,MAVEN_CACHE_STATS,MAVEN_MODEL_PROCESSOR_POOLED_TYPES). Both are missing here.
Low
-
Parameters missing
@Nonnull/@Nullable(TempFileService.java) — Other services in this package annotate all parameters (Interpolator,ArtifactManager). Thesessionanddirectoryparameters should be@Nonnull; clarify whetherprefix/suffixaccept null (they do perjava.nio.file.Filescontract). -
Logger created inline (
TempFileCleanupParticipant.java) — The logger is created at the call site:LoggerFactory.getLogger(TempFileCleanupParticipant.class).warn(...). This is inconsistent withDefaultTempFileServicein the same PR, which correctly uses aprivate static final Logger LOGGERfield. Extract to a field. -
System.setPropertyin tests (DefaultTempFileServiceTest.java) —System.setPropertymutates global JVM state and can cause test pollution in parallel execution. Also, there is no test forTempFileCleanupParticipantitself. -
Raw type cast for
TMP_KEY(DefaultTempFileService.java) — The@SuppressWarnings({"unchecked", "rawtypes"})cast is acknowledged and documented. Consider a wrapper type to avoid the raw cast, or accept it as a known limitation ofSessionData.Keygenerics.
Notes
- The companion PR #11389 targeting
maven-4.Xis closed. Please confirm this is the intended target branch. - The PR description is minimal — for a new public API addition, documenting the motivation (what temp files are currently leaked, which plugins benefit) would help reviewers.
- Thread safety looks correct:
ConcurrentHashMap-backedSetandSessionData.computeIfAbsentprovide atomic initialization. - No new dependencies introduced.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of Guillaume Nodet
Reviewed 3 PRs: apache#12454 (re-review), apache#11502 (new), apache#11405 (new). Added 2 new dependabot PRs to skip list. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
gnodet
left a comment
There was a problem hiding this comment.
New TempFileService API with lifecycle cleanup — solid concept for managing build temp files. All findings below were independently verified (7/7 confirmed).
Note: a maintainer (gnodet) already submitted CHANGES_REQUESTED in November 2025, and these issues remain unaddressed after 8+ months.
Convention violations:
- @nonnull on void returns (high) —
register()andcleanup()apply@Nonnullto the void return type. Existing services apply it to parameters instead. - Missing @experimental (medium) — All 20+ Service interfaces carry
@Experimental. Also missing@since 4.1.0. - KEEP_PROP naming (medium) — All 113 other constants use the
MAVEN_prefix. Should beMAVEN_TEMPFILE_KEEP. Also missing@Configand@since 4.1.0. (Already noted by gnodet in Nov 2025 review.) - Boolean.getBoolean limitation (medium) — Only reads JVM
-Dproperties, not Maven session properties from pom.xml/profiles/settings.xml. Should be documented if intentional. - Inline logger (low) —
TempFileCleanupParticipantcreates logger inline;DefaultTempFileServiceuses standardprivate static final Logger. - Missing parameter annotations (low) —
session,directory,prefix,suffixparameters lack@Nonnull/@Nullable. - System.setProperty in test (low) — Mutates global JVM state;
@AfterEachcleanup present but can still cause flakiness under parallel execution. No test forTempFileCleanupParticipant.
This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.
Claude Code on behalf of gnodet
| * Registers an externally created path for cleanup at session end. | ||
| */ | ||
| @Nonnull | ||
| void register(Session session, Path path); |
There was a problem hiding this comment.
@Nonnull on a void return type is semantically meaningless. In existing services (ArtifactDeployer.deploy, ArtifactManager.setPath), @Nonnull is applied to parameters, not void returns.
Same issue on cleanup() below.
| void register(Session session, Path path); | |
| void register(@Nonnull Session session, @Nonnull Path path); |
| * System property to keep temp material for diagnostics. | ||
| * | ||
| */ | ||
| public static final String KEEP_PROP = "maven.tempfile.keep"; |
There was a problem hiding this comment.
All 113 other constants in this file use the MAVEN_ prefix (MAVEN_HOME, MAVEN_CACHE_STATS, MAVEN_REPO_LOCAL, etc.). This should be MAVEN_TEMPFILE_KEEP. Also missing @since 4.1.0 and @Config annotation (71 other constants have @Config).
| public static final String KEEP_PROP = "maven.tempfile.keep"; | |
| /** | |
| * System property to keep temp material for diagnostics. | |
| * | |
| * @since 4.1.0 | |
| */ | |
| @Config(type = "java.lang.Boolean", defaultValue = "false") | |
| public static final String MAVEN_TEMPFILE_KEEP = "maven.tempfile.keep"; |
gnodet
left a comment
There was a problem hiding this comment.
Review Summary
The TempFileService design is clean and follows Maven 4 service conventions well — using SessionData for per-session tracking, @Singleton supporting multiple sessions, and the AbstractMavenLifecycleParticipant for cleanup are all consistent with existing patterns.
The existing review feedback from @gnodet (constant naming to MAVEN_TEMPFILE_KEEP, adding @Config/@since, removing @Nonnull on void methods) appears to have been addressed in the second commit.
Two robustness issues in the deleteTree cleanup logic and a minor test coverage gap:
1. 🐛 Missing visitFileFailed override in deleteTree (medium)
File: impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultTempFileService.java
The SimpleFileVisitor in deleteTree does not override visitFileFailed. The default implementation re-throws the IOException, causing walkFileTree to abort immediately. On Windows where files can be locked by antivirus or other processes, a single inaccessible file prevents cleanup of the entire directory tree.
Suggestion: Override visitFileFailed to log and return CONTINUE for best-effort cleanup:
@Override
public FileVisitResult visitFileFailed(final Path file, final IOException exc) {
LOGGER.debug("Could not access temp file for deletion: {}", file, exc);
return FileVisitResult.CONTINUE;
}2. 🐛 postVisitDirectory should catch DirectoryNotEmptyException (medium)
File: impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultTempFileService.java
The postVisitDirectory override silently drops the exc parameter but does not wrap Files.deleteIfExists(dir) in a try-catch. If any children were not deleted (e.g., due to a locked file after fixing issue 1), deleteIfExists throws DirectoryNotEmptyException, which propagates through walkFileTree and aborts cleanup of the remaining tree.
Suggestion: Wrap in try-catch for best-effort cleanup:
@Override
public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) {
try {
Files.deleteIfExists(dir);
} catch (final IOException e) {
LOGGER.debug("Could not delete temp directory: {}", dir, e);
}
return FileVisitResult.CONTINUE;
}These two issues are interrelated — fixing #1 makes #2 more likely to trigger, so both should be addressed together.
3. Missing test coverage (low)
File: impl/maven-core/src/test/java/org/apache/maven/internal/impl/DefaultTempFileServiceTest.java
The tests only exercise the no-directory overloads. The directory-parameter overloads (createTempFile(session, prefix, suffix, directory) and createTempDirectory(session, prefix, directory)) exercise different Files.createTempFile(directory, ...) / Files.createTempDirectory(directory, ...) code paths and have their own Objects.requireNonNull(directory) guard, none of which is tested.
🤖 This review was generated by ForgeBot. Feedback? File an issue on the ForgeBot repo.
f97429a to
4f46518
Compare
4f46518 to
0427c6a
Compare
|
Rebased on master and squashed. The earlier requests are already in ( |
gnodet-bot
left a comment
There was a problem hiding this comment.
All prior findings from @gnodet's review (November 2025) and subsequent bot reviews have been addressed in the squashed commit: MAVEN_TEMPFILE_KEEP naming ✓, @Config/@since ✓, @Nonnull removed from void returns ✓, @Experimental ✓, static logger in TempFileCleanupParticipant ✓, visitFileFailed override ✓, postVisitDirectory try-catch ✓, directory-overload tests ✓, and parameter null annotations ✓.
Two remaining issues prevent a clean merge.
This review was generated by an AI agent, Hermès on behalf of @gnodet.
Add TempFileService, an experimental API to create temporary files and directories which are tracked per session, and delete them at the end of the session through a lifecycle participant. Cleanup is best effort: a file which cannot be deleted does not prevent the deletion of the others. Setting the maven.tempfile.keep system property to true keeps them for diagnostics.
0427c6a to
4fb7c4c
Compare
gnodet-bot
left a comment
There was a problem hiding this comment.
👋 Re-reviewing after the new squash commit.
✅ All four prior findings are addressed:
@Configsource corrected and@throwsadded throughout- Stack trace preserved in exception handling
@throwsadded to all factory methods andcleanup()System.setPropertynow guarded with try-finally
One new issue remains.
This review was generated by an AI agent, Hermès on behalf of @gnodet.
| * @throws IOException if the path cannot be created | ||
| */ | ||
| @Nonnull | ||
| Path createTempFile(@Nonnull Session session, @Nullable String prefix, @Nullable String suffix) throws IOException; |
There was a problem hiding this comment.
📝 Missing @param and @return tags on all factory methods
All six methods in this interface have Javadoc but are missing @param and @return documentation. Every other Maven 4 API service interface (ArtifactResolver, DependencyResolver, VersionResolver, etc.) consistently documents all parameters and return values with Javadoc tags.
For example, createTempFile(Session, String, String) should read:
| Path createTempFile(@Nonnull Session session, @Nullable String prefix, @Nullable String suffix) throws IOException; | |
| /** | |
| * Creates a temp file in the default temp directory. | |
| * | |
| * @param session the Maven session, must not be {@code null} | |
| * @param prefix the prefix string to be used in generating the file's name; may be {@code null} | |
| * @param suffix the suffix string to be used in generating the file's name; may be {@code null} | |
| * @return the path to the newly created temp file, never {@code null} | |
| * @throws IOException if the path cannot be created | |
| */ |
Please add @param and @return tags to all six methods (createTempFile ×2, createTempDirectory ×2, register, cleanup).
Following this checklist to help us incorporate your
contribution quickly and easily:
If your pull request is about ~20 lines of code you don't need to sign an
Individual Contributor License Agreement if you are unsure
please ask on the developers list.
To make clear that you license your contribution under
the Apache License Version 2.0, January 2004
you have to acknowledge this by using the following check-box.
I hereby declare this contribution to be licenced under the Apache License Version 2.0, January 2004
In any other case, please file an Apache Individual Contributor License Agreement.