From 2ae34a5b6a19cc32484600ef0b47c92d9536444b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dr=2E=20Christian=20Kohlsch=C3=BCtter?= Date: Fri, 22 Dec 2023 12:42:16 +0100 Subject: [PATCH] Workaround for "m2e plugin sometimes 'loses' resources" The Java Builder may delete files from the project output directory that need to be re-created by the m2e Maven Builder. With commit 8e5cd4967eaca2698e8f7109461320e11a11d4d7, any changes to the project output directory were ignored, leading to unexpected errors when running an application after modifying the project POM: resources were missing from the target classpath, leading all sorts of unexpected program behavior. This change allows marking these changes as relevant, as long as the following conditions are met: - The expected resource no longer exists (i.e., it was deleted by another builder, plugin or outside process) - The modification applies to a resource in the classes or test-classes folder (i.e., outputLocation/testOutputLocation) See https://github.com/eclipse-m2e/m2e-core/issues/1511 See https://github.com/eclipse-m2e/m2e-core/issues/1275 --- org.eclipse.m2e.core/META-INF/MANIFEST.MF | 2 +- org.eclipse.m2e.core/pom.xml | 2 +- .../internal/builder/MavenBuilderImpl.java | 19 ++++++++++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/org.eclipse.m2e.core/META-INF/MANIFEST.MF b/org.eclipse.m2e.core/META-INF/MANIFEST.MF index fca7d3c36..850a6505f 100644 --- a/org.eclipse.m2e.core/META-INF/MANIFEST.MF +++ b/org.eclipse.m2e.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.m2e.core;singleton:=true -Bundle-Version: 2.4.1.qualifier +Bundle-Version: 2.4.2.qualifier Bundle-Activator: org.eclipse.m2e.core.internal.MavenPluginActivator Bundle-Vendor: %Bundle-Vendor Bundle-Localization: plugin diff --git a/org.eclipse.m2e.core/pom.xml b/org.eclipse.m2e.core/pom.xml index b4a184c85..2d0e3c50a 100644 --- a/org.eclipse.m2e.core/pom.xml +++ b/org.eclipse.m2e.core/pom.xml @@ -19,7 +19,7 @@ org.eclipse.m2e.core - 2.4.1-SNAPSHOT + 2.4.2-SNAPSHOT eclipse-plugin Maven Integration for Eclipse Core Plug-in diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/builder/MavenBuilderImpl.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/builder/MavenBuilderImpl.java index 6b88fda39..931bbd80f 100644 --- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/builder/MavenBuilderImpl.java +++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/builder/MavenBuilderImpl.java @@ -29,6 +29,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Predicate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -209,6 +210,11 @@ private boolean hasRelevantDelta(IMavenProjectFacade projectFacade, IResourceDel if(project == null || buildOutputLocation == null) { return true; } + + Predicate isOutput = toPrefixPredicate(projectFacade.getOutputLocation()); + Predicate isTestOutput = toPrefixPredicate(projectFacade.getTestOutputLocation()); + Predicate isOutputOrTestOutput = isOutput.or(isTestOutput); + IPath projectPath = project.getFullPath(); List moduleLocations = projectFacade.getMavenProjectModules().stream() .map(module -> projectPath.append(module)).toList(); @@ -219,7 +225,11 @@ private boolean hasRelevantDelta(IMavenProjectFacade projectFacade, IResourceDel IPath fullPath = delta.getFullPath(); if(buildOutputLocation.isPrefixOf(fullPath)) { //anything in the build output is not interesting for a change as it is produced by the build - //lets see if there are more interesting parts... + // ... unless a classpath resource that existed before has been deleted, possibly by another builder + if(isOutputOrTestOutput.test(fullPath) && !resource.exists()) { + hasRelevantDelta.set(true); + return false; + } return true; } for(IPath modulePath : moduleLocations) { @@ -237,6 +247,13 @@ private boolean hasRelevantDelta(IMavenProjectFacade projectFacade, IResourceDel return hasRelevantDelta.get(); } + private static Predicate toPrefixPredicate(IPath location) { + if(location == null) { + return (p) -> false; + } + return (p) -> location.isPrefixOf(p); + } + private List setupProjectBuildContext(IProject project, int kind, IResourceDelta delta, IIncrementalBuildFramework.BuildResultCollector results, ProjectBuildState buildState) throws CoreException {