You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by gn...@apache.org on 2026/08/03 00:36:48 UTC
(maven-install-plugin) 01/01: Cache projectsUsingPlugin list to avoid O(N²) reactor scan
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch quick-fix/cache-projects-using-plugin
in repository https://gitbox.apache.org/repos/asf/maven-install-plugin.git
commit 05e6221587f26c87282769820e9d9088e2ff1301
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Mon Aug 3 02:36:22 2026 +0200
Cache projectsUsingPlugin list to avoid O(N²) reactor scan
InstallMojo.execute() computes the list of reactor projects using
the install plugin on every module invocation by streaming over all
projects and calling getPluginsAsMap() for each one. In a 4383-module
reactor, this produces ~19.2M filter evaluations (4383² calls).
JFR profiling shows this as 5.6% of total CPU time, all in
PluginContainer.getPluginsAsMap() called from usingPlugin().
Fix: cache the computed list in the first reactor project's plugin
context on first invocation. The list is invariant during a build —
which projects have the install plugin configured does not change
between module invocations. This turns O(N²) into O(N).
Co-Authored-By: Claude Opus 4.6 <no...@anthropic.com>
---
.../apache/maven/plugins/install/InstallMojo.java | 24 ++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/src/main/java/org/apache/maven/plugins/install/InstallMojo.java b/src/main/java/org/apache/maven/plugins/install/InstallMojo.java
index d002520..f3183f5 100644
--- a/src/main/java/org/apache/maven/plugins/install/InstallMojo.java
+++ b/src/main/java/org/apache/maven/plugins/install/InstallMojo.java
@@ -98,6 +98,7 @@ public class InstallMojo implements org.apache.maven.api.plugin.Mojo {
}
private static final String INSTALL_PROCESSED_MARKER = InstallMojo.class.getName() + ".processed";
+ private static final String PROJECTS_USING_PLUGIN_KEY = InstallMojo.class.getName() + ".projectsUsingPlugin";
public InstallMojo() {}
@@ -120,6 +121,26 @@ public class InstallMojo implements org.apache.maven.api.plugin.Mojo {
return pluginContext.containsKey(INSTALL_PROCESSED_MARKER);
}
+ /**
+ * Returns the list of reactor projects that have this plugin configured, cached on first call.
+ * The list is invariant during a build and is stored in the current project's plugin
+ * context to avoid recomputing it on every module invocation (O(N) total instead of O(N²)).
+ */
+ @SuppressWarnings("unchecked")
+ private List<Project> getProjectsUsingPlugin() {
+ List<Project> allProjects = session.getProjects();
+ if (allProjects.isEmpty()) {
+ return List.of();
+ }
+ Map<String, Object> ctx = session.getPluginContext(allProjects.get(0));
+ List<Project> cached = (List<Project>) ctx.get(PROJECTS_USING_PLUGIN_KEY);
+ if (cached == null) {
+ cached = allProjects.stream().filter(this::usingPlugin).collect(Collectors.toList());
+ ctx.put(PROJECTS_USING_PLUGIN_KEY, cached);
+ }
+ return cached;
+ }
+
private boolean usingPlugin(Project project) {
Plugin plugin = project.getBuild().getPluginsAsMap().get("org.apache.maven.plugins:maven-install-plugin");
return plugin != null
@@ -144,8 +165,7 @@ public class InstallMojo implements org.apache.maven.api.plugin.Mojo {
}
}
- List<Project> projectsUsingPlugin =
- session.getProjects().stream().filter(this::usingPlugin).collect(Collectors.toList());
+ List<Project> projectsUsingPlugin = getProjectsUsingPlugin();
if (allProjectsMarked(projectsUsingPlugin)) {
for (Project reactorProject : projectsUsingPlugin) {
State state = getState(reactorProject);