From 58f1004d57bba6657022c820b1452b4f1243c4dc Mon Sep 17 00:00:00 2001 From: Martin Kanters Date: Wed, 29 Jan 2020 16:21:39 +0100 Subject: [PATCH 01/19] [MNG-4660] Include already built submodules in Reactor for local dependency resolving. --- .../main/java/org/apache/maven/ReactorReader.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index 831a4b6599a4..b9434ee092a6 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -66,7 +66,12 @@ class ReactorReader @Inject ReactorReader( MavenSession session ) { - projectsByGAV = session.getProjectMap(); + this.projectsByGAV = new HashMap<>( session.getAllProjects().size() * 2 ); + session.getAllProjects().forEach( project -> + { + String projectId = ArtifactUtils.key( project.getGroupId(), project.getArtifactId(), project.getVersion() ); + this.projectsByGAV.put( projectId, project ); + } ); projectsByGA = new HashMap<>( projectsByGAV.size() * 2 ); for ( MavenProject project : projectsByGAV.values() ) @@ -172,9 +177,13 @@ else if ( !hasBeenPackaged( project ) ) else { String type = artifact.getProperty( "type", "" ); - if ( project.hasLifecyclePhase( "compile" ) && COMPILE_PHASE_TYPES.contains( type ) ) + if ( COMPILE_PHASE_TYPES.contains( type ) ) { - return new File( project.getBuild().getOutputDirectory() ); + File outputDirectory = new File( project.getBuild().getOutputDirectory() ); + if ( outputDirectory.exists() ) + { + return outputDirectory; + } } } } From d957f725255ca22dec7f77d265f7b2ae882ea019 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Wed, 29 Jan 2020 21:35:10 +0100 Subject: [PATCH 02/19] [MNG-4660] Do not check whether calculated directory actually exists --- .../src/main/java/org/apache/maven/ReactorReader.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index b9434ee092a6..f840cb510fe5 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -179,11 +179,7 @@ else if ( !hasBeenPackaged( project ) ) String type = artifact.getProperty( "type", "" ); if ( COMPILE_PHASE_TYPES.contains( type ) ) { - File outputDirectory = new File( project.getBuild().getOutputDirectory() ); - if ( outputDirectory.exists() ) - { - return outputDirectory; - } + return new File( project.getBuild().getOutputDirectory() ); } } } From 9eea00e919341bb726436c3e88f22769d3a335f7 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Fri, 14 Feb 2020 12:49:53 +0100 Subject: [PATCH 03/19] [MNG-4660] Inspect all projects in Reactor when retrieving metadata --- .../maven/project/artifact/MavenMetadataSource.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java b/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java index 1c40af8b9869..cacbd9d88b18 100644 --- a/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java +++ b/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java @@ -194,9 +194,11 @@ public ResolutionGroup retrieve( MetadataResolutionRequest request ) DependencyManagement dependencyManagement = model.getDependencyManagement(); managedDependencies = dependencyManagement == null ? null : dependencyManagement.getDependencies(); MavenSession session = legacySupport.getSession(); - MavenProject project = session.getProjectMap().get( - ArtifactUtils.key( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() ) ); - pomRepositories = project.getRemoteArtifactRepositories(); + pomRepositories = session.getProjects().stream() + .filter(p -> artifact.equals( p.getArtifact() ) ) + .map(MavenProject::getRemoteArtifactRepositories) + .findFirst() + .orElseGet(ArrayList::new); } else if ( artifact instanceof ArtifactWithDependencies ) { From 5474e229aef7e5957ae0cf8ba8dd618323349da0 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Fri, 14 Feb 2020 12:50:18 +0100 Subject: [PATCH 04/19] [MNG-4660] Update comment --- .../src/main/java/org/apache/maven/execution/MavenSession.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java b/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java index 5b56df36d003..8da252fb5480 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java +++ b/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java @@ -297,7 +297,7 @@ public void setAllProjects( List allProjects ) private final Settings settings; @Deprecated - /** @deprecated This appears to only be used in the ReactorReader and we can do any processing required there */ + /** @deprecated This appears not to be used anywhere within Maven itself. */ public Map getProjectMap() { return projectMap; From 58786238eb50dfca50f838fda3878c92fab3bcdb Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Fri, 14 Feb 2020 12:51:16 +0100 Subject: [PATCH 05/19] [MNG-4660] Make ReactorReader aware of possible previous built artifacts --- .../java/org/apache/maven/ReactorReader.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index f840cb510fe5..7c52ff2e9569 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -157,12 +157,18 @@ private File find( MavenProject project, Artifact artifact ) } Artifact projectArtifact = findMatchingArtifact( project, artifact ); + File packagedArtifactFile = determinePreviouslyPackagedArtifactFile( project, projectArtifact ); if ( hasArtifactFileFromPackagePhase( projectArtifact ) ) { return projectArtifact.getFile(); } - else if ( !hasBeenPackaged( project ) ) + // Check whether an earlier Maven run might have produced an artifact that is still on disk. + else if ( packagedArtifactFile != null && packagedArtifactFile.exists() ) + { + return packagedArtifactFile; + } + else if ( !hasBeenPackagedDuringThisSession( project ) ) { // fallback to loose class files only if artifacts haven't been packaged yet // and only for plain old jars. Not war files, not ear files, not anything else. @@ -189,12 +195,23 @@ else if ( !hasBeenPackaged( project ) ) return null; } + private File determinePreviouslyPackagedArtifactFile( MavenProject project, Artifact artifact ) + { + if ( artifact == null ) + { + return null; + } + + String fileName = String.format( "%s.%s", project.getBuild().getFinalName(), artifact.getExtension() ); + return new File( project.getBuild().getDirectory(), fileName ); + } + private boolean hasArtifactFileFromPackagePhase( Artifact projectArtifact ) { return projectArtifact != null && projectArtifact.getFile() != null && projectArtifact.getFile().exists(); } - private boolean hasBeenPackaged( MavenProject project ) + private boolean hasBeenPackagedDuringThisSession( MavenProject project ) { return project.hasLifecyclePhase( "package" ) || project.hasLifecyclePhase( "install" ) || project.hasLifecyclePhase( "deploy" ); From ea4ce10b915a50a2b7fecf74822274d6f3007f75 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Fri, 14 Feb 2020 15:18:30 +0100 Subject: [PATCH 06/19] [MNG-4660] Only use module output directory when it has been compiled in this session --- maven-core/src/main/java/org/apache/maven/ReactorReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index 7c52ff2e9569..2bfb9ee799a3 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -183,7 +183,7 @@ else if ( !hasBeenPackagedDuringThisSession( project ) ) else { String type = artifact.getProperty( "type", "" ); - if ( COMPILE_PHASE_TYPES.contains( type ) ) + if ( project.hasLifecyclePhase( "compile" ) && COMPILE_PHASE_TYPES.contains( type ) ) { return new File( project.getBuild().getOutputDirectory() ); } From 0e9c66d50be406a4c3633c61943162130d00799c Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Fri, 14 Feb 2020 13:40:28 +0100 Subject: [PATCH 07/19] [MNG-4660] Update contributors list --- pom.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3148a971eba0..c8f9e50fc7ed 100644 --- a/pom.xml +++ b/pom.xml @@ -158,7 +158,12 @@ under the License. Mike Mol (MNG-6665) - Martin Kanters (MNG-6665, MNG-6065) + Martin Kanters + Info Support + + + Maarten Mulders + Info Support Luc Klaassen (MNG-6065) From ea09c473743bfb29cf3cbba309217924991381a4 Mon Sep 17 00:00:00 2001 From: Martin Kanters Date: Mon, 9 Mar 2020 12:29:26 +0100 Subject: [PATCH 08/19] [MNG-4660] Prefer the target/classes directory when the packaged artifact is not up-to-date. --- .../java/org/apache/maven/ReactorReader.java | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index 2bfb9ee799a3..3f320a10950a 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -20,6 +20,10 @@ */ import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -28,6 +32,8 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Stream; import javax.inject.Inject; import javax.inject.Named; @@ -37,6 +43,7 @@ import org.apache.maven.model.Model; import org.apache.maven.project.MavenProject; import org.apache.maven.repository.internal.MavenWorkspaceReader; +import org.codehaus.plexus.logging.Logger; import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.repository.WorkspaceRepository; import org.eclipse.aether.util.artifact.ArtifactIdUtils; @@ -57,6 +64,8 @@ class ReactorReader private static final Collection COMPILE_PHASE_TYPES = Arrays.asList( "jar", "ejb-client", "war", "rar", "ejb3", "par", "sar", "wsr", "har", "app-client" ); + private Logger logger; + private Map projectsByGAV; private Map> projectsByGA; @@ -64,8 +73,9 @@ class ReactorReader private WorkspaceRepository repository; @Inject - ReactorReader( MavenSession session ) + ReactorReader( MavenSession session, Logger logger ) { + this.logger = logger; this.projectsByGAV = new HashMap<>( session.getAllProjects().size() * 2 ); session.getAllProjects().forEach( project -> { @@ -164,7 +174,8 @@ private File find( MavenProject project, Artifact artifact ) return projectArtifact.getFile(); } // Check whether an earlier Maven run might have produced an artifact that is still on disk. - else if ( packagedArtifactFile != null && packagedArtifactFile.exists() ) + else if ( packagedArtifactFile != null && packagedArtifactFile.exists() + && isPackagedArtifactUpToDate( project, packagedArtifactFile ) ) { return packagedArtifactFile; } @@ -211,6 +222,36 @@ private boolean hasArtifactFileFromPackagePhase( Artifact projectArtifact ) return projectArtifact != null && projectArtifact.getFile() != null && projectArtifact.getFile().exists(); } + private boolean isPackagedArtifactUpToDate( MavenProject project, File packagedArtifactFile ) + { + Path outputDirectory = Paths.get( project.getBuild().getOutputDirectory() ); + if ( !outputDirectory.toFile().exists() ) + { + return true; + } + + try ( Stream outputFiles = Files.list( outputDirectory ) ) + { + long artifactLastModified = packagedArtifactFile.lastModified(); + Predicate isNewerThanPackagedArtifact = path -> path.toFile().lastModified() > artifactLastModified; + boolean isPackagedArtifactUpToDate = outputFiles.noneMatch( isNewerThanPackagedArtifact ); + + if ( !isPackagedArtifactUpToDate ) + { + logger.warn( "Packaged artifact is not up-to-date compared to the build output directory" ); + } + + return isPackagedArtifactUpToDate; + } + catch ( IOException e ) + { + logger.warn( "An I/O error occurred while checking if the packaged artifact is up-to-date " + + "against the build output directory. " + + "Continuing with the assumption that it is up-to-date.", e ); + return true; + } + } + private boolean hasBeenPackagedDuringThisSession( MavenProject project ) { return project.hasLifecyclePhase( "package" ) || project.hasLifecyclePhase( "install" ) From 8056b59478518449a7d56e35f180cd4f9951f7d8 Mon Sep 17 00:00:00 2001 From: Martin Kanters Date: Mon, 9 Mar 2020 14:22:25 +0100 Subject: [PATCH 09/19] [MNG-4660] Use Files.walk instead of .list to recursively check for newer class files when checking if the packaged artifact is up-to-date --- maven-core/src/main/java/org/apache/maven/ReactorReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index 3f320a10950a..e0296609473e 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -230,7 +230,7 @@ private boolean isPackagedArtifactUpToDate( MavenProject project, File packagedA return true; } - try ( Stream outputFiles = Files.list( outputDirectory ) ) + try ( Stream outputFiles = Files.walk( outputDirectory ) ) { long artifactLastModified = packagedArtifactFile.lastModified(); Predicate isNewerThanPackagedArtifact = path -> path.toFile().lastModified() > artifactLastModified; From 0c98c5ef28284f16fe1e4bd94bba44e9196f04d2 Mon Sep 17 00:00:00 2001 From: Martin Kanters Date: Thu, 26 Mar 2020 11:17:16 +0100 Subject: [PATCH 10/19] [mng-4660] Also include build output directory when the project does not have a compile lifecycle when reading local artifacts. This is needed for resolving intermodule dependencies which are not built in this session (for example with -rf, -pl flags). --- maven-core/src/main/java/org/apache/maven/ReactorReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index e0296609473e..7c856681b072 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -194,7 +194,7 @@ else if ( !hasBeenPackagedDuringThisSession( project ) ) else { String type = artifact.getProperty( "type", "" ); - if ( project.hasLifecyclePhase( "compile" ) && COMPILE_PHASE_TYPES.contains( type ) ) + if ( COMPILE_PHASE_TYPES.contains( type ) ) { return new File( project.getBuild().getOutputDirectory() ); } From c496592348020b81f2c3b60f44009b4c0b70ad7b Mon Sep 17 00:00:00 2001 From: Martin Kanters Date: Thu, 26 Mar 2020 11:18:19 +0100 Subject: [PATCH 11/19] [mng-4660] Checkstyle fixes --- .../apache/maven/project/artifact/MavenMetadataSource.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java b/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java index cacbd9d88b18..1c718e388f14 100644 --- a/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java +++ b/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java @@ -195,10 +195,10 @@ public ResolutionGroup retrieve( MetadataResolutionRequest request ) managedDependencies = dependencyManagement == null ? null : dependencyManagement.getDependencies(); MavenSession session = legacySupport.getSession(); pomRepositories = session.getProjects().stream() - .filter(p -> artifact.equals( p.getArtifact() ) ) - .map(MavenProject::getRemoteArtifactRepositories) + .filter( p -> artifact.equals( p.getArtifact() ) ) + .map( MavenProject::getRemoteArtifactRepositories ) .findFirst() - .orElseGet(ArrayList::new); + .orElseGet( ArrayList::new ); } else if ( artifact instanceof ArtifactWithDependencies ) { From bff090b26e1d7b7718e2d5fc6d3c9a5ef63b6071 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 26 Mar 2020 13:59:38 +0100 Subject: [PATCH 12/19] [MNG-4660] More sophisticated rules for determining project artifact It now properly distinguishes between two situations: 1. project artifact has been built during earlier Maven session 2. project artifact has been built during this session --- .../java/org/apache/maven/ReactorReader.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index 7c856681b072..71e70b9b84e9 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -194,9 +194,22 @@ else if ( !hasBeenPackagedDuringThisSession( project ) ) else { String type = artifact.getProperty( "type", "" ); - if ( COMPILE_PHASE_TYPES.contains( type ) ) + File outputDirectory = new File( project.getBuild().getOutputDirectory() ); + + // Check if the target project is being built during this session, and if we can expect any output. + // There is no need to check if the build has created any outputs, see MNG-2222. + boolean projectCompiledDuringThisSession + = project.hasLifecyclePhase( "compile" ) && COMPILE_PHASE_TYPES.contains( type ); + + // Check if the target project lacks 'validate' so we know it's not part of the build at all. If so, we + // check if a possible earlier Maven invocation produced some output for that project. + boolean projectHasOutputFromPreviousSession + = !project.hasLifecyclePhase( "validate" ) && outputDirectory.exists(); + + if ( projectHasOutputFromPreviousSession || projectCompiledDuringThisSession ) { - return new File( project.getBuild().getOutputDirectory() ); + // If the target project is not part of the build, + return outputDirectory; } } } From a79ee04c8905c1cd2a594fd510652c5117d0a7d1 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Thu, 26 Mar 2020 14:10:47 +0100 Subject: [PATCH 13/19] [MNG-4660] Remove obsolete comment --- maven-core/src/main/java/org/apache/maven/ReactorReader.java | 1 - 1 file changed, 1 deletion(-) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index 71e70b9b84e9..0d28a3a503d8 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -208,7 +208,6 @@ else if ( !hasBeenPackagedDuringThisSession( project ) ) if ( projectHasOutputFromPreviousSession || projectCompiledDuringThisSession ) { - // If the target project is not part of the build, return outputDirectory; } } From 8ffb33c347bd3f302e9d78ea3d199eda6fdc3d3c Mon Sep 17 00:00:00 2001 From: Martin Kanters Date: Thu, 26 Mar 2020 18:09:28 +0100 Subject: [PATCH 14/19] [MNG-4660] Replace checking if the project has the lifecyclePhase "validate" by checking if the project consists in the reactor. --- .../src/main/java/org/apache/maven/ReactorReader.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index 0d28a3a503d8..ddc74f7b52ba 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -66,6 +66,8 @@ class ReactorReader private Logger logger; + private MavenSession session; + private Map projectsByGAV; private Map> projectsByGA; @@ -76,6 +78,7 @@ class ReactorReader ReactorReader( MavenSession session, Logger logger ) { this.logger = logger; + this.session = session; this.projectsByGAV = new HashMap<>( session.getAllProjects().size() * 2 ); session.getAllProjects().forEach( project -> { @@ -196,15 +199,15 @@ else if ( !hasBeenPackagedDuringThisSession( project ) ) String type = artifact.getProperty( "type", "" ); File outputDirectory = new File( project.getBuild().getOutputDirectory() ); - // Check if the target project is being built during this session, and if we can expect any output. + // Check if the project is being built during this session, and if we can expect any output. // There is no need to check if the build has created any outputs, see MNG-2222. boolean projectCompiledDuringThisSession = project.hasLifecyclePhase( "compile" ) && COMPILE_PHASE_TYPES.contains( type ); - // Check if the target project lacks 'validate' so we know it's not part of the build at all. If so, we - // check if a possible earlier Maven invocation produced some output for that project. + // Check if the project is part of the session (not filtered by -pl, -rf, etc). If so, we check + // if a possible earlier Maven invocation produced some output for that project which we can use. boolean projectHasOutputFromPreviousSession - = !project.hasLifecyclePhase( "validate" ) && outputDirectory.exists(); + = !session.getProjects().contains( project ) && outputDirectory.exists(); if ( projectHasOutputFromPreviousSession || projectCompiledDuringThisSession ) { From 3064231df0e4c94ee2ac5dc989e9d7205ea6b8c8 Mon Sep 17 00:00:00 2001 From: Martin Kanters Date: Sat, 28 Mar 2020 15:22:40 +0100 Subject: [PATCH 15/19] [MNG-4660] Checkstyle - Removed unused import --- .../org/apache/maven/project/artifact/MavenMetadataSource.java | 1 - 1 file changed, 1 deletion(-) diff --git a/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java b/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java index 1c718e388f14..6b3a09a7b6dc 100644 --- a/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java +++ b/maven-core/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java @@ -34,7 +34,6 @@ import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; From a466d8a26a2b5aad42b41861a4c9744de64136b8 Mon Sep 17 00:00:00 2001 From: Martin Kanters Date: Sun, 29 Mar 2020 17:16:34 +0200 Subject: [PATCH 16/19] [MNG-4660] Using Files.getLastModifiedTime instead of File#lastModified to avoid a bug in JDK8 on linux. --- .../java/org/apache/maven/ReactorReader.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index ddc74f7b52ba..13d7205a6f8f 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -32,7 +32,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.function.Predicate; +import java.util.stream.Collectors; import java.util.stream.Stream; import javax.inject.Inject; @@ -247,16 +247,20 @@ private boolean isPackagedArtifactUpToDate( MavenProject project, File packagedA try ( Stream outputFiles = Files.walk( outputDirectory ) ) { - long artifactLastModified = packagedArtifactFile.lastModified(); - Predicate isNewerThanPackagedArtifact = path -> path.toFile().lastModified() > artifactLastModified; - boolean isPackagedArtifactUpToDate = outputFiles.noneMatch( isNewerThanPackagedArtifact ); + // Not using File#lastModified() to avoid a Linux JDK8 milliseconds precision bug: JDK-8177809. + long artifactLastModified = Files.getLastModifiedTime( packagedArtifactFile.toPath() ).toMillis(); - if ( !isPackagedArtifactUpToDate ) + for ( Path outputFile : outputFiles.collect( Collectors.toList() ) ) { - logger.warn( "Packaged artifact is not up-to-date compared to the build output directory" ); + long outputFileLastModified = Files.getLastModifiedTime( outputFile ).toMillis(); + if ( outputFileLastModified > artifactLastModified ) + { + logger.warn( "Packaged artifact is not up-to-date compared to the build output directory" ); + return false; + } } - return isPackagedArtifactUpToDate; + return true; } catch ( IOException e ) { From ee8ff87873f4e9443be5aae4cd51d8a0ed40f599 Mon Sep 17 00:00:00 2001 From: Maarten Mulders Date: Sun, 29 Mar 2020 21:28:46 +0200 Subject: [PATCH 17/19] [MNG-4660] Use Stream#iterator to lazily traverse outputFiles --- .../src/main/java/org/apache/maven/ReactorReader.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index 13d7205a6f8f..ebcf4522b081 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -30,9 +30,9 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import java.util.stream.Stream; import javax.inject.Inject; @@ -250,8 +250,10 @@ private boolean isPackagedArtifactUpToDate( MavenProject project, File packagedA // Not using File#lastModified() to avoid a Linux JDK8 milliseconds precision bug: JDK-8177809. long artifactLastModified = Files.getLastModifiedTime( packagedArtifactFile.toPath() ).toMillis(); - for ( Path outputFile : outputFiles.collect( Collectors.toList() ) ) + Iterator iterator = outputFiles.iterator(); + while ( iterator.hasNext() ) { + Path outputFile = iterator.next(); long outputFileLastModified = Files.getLastModifiedTime( outputFile ).toMillis(); if ( outputFileLastModified > artifactLastModified ) { From 043b59d91cf3564e0e78b9631ab76f56483d7646 Mon Sep 17 00:00:00 2001 From: Martin Kanters Date: Mon, 30 Mar 2020 08:27:41 +0200 Subject: [PATCH 18/19] [MNG-4660] Take the build time into account when determining if the packaged artifact is up to date. --- .../src/main/java/org/apache/maven/ReactorReader.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index ebcf4522b081..846435bbca22 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -250,6 +250,12 @@ private boolean isPackagedArtifactUpToDate( MavenProject project, File packagedA // Not using File#lastModified() to avoid a Linux JDK8 milliseconds precision bug: JDK-8177809. long artifactLastModified = Files.getLastModifiedTime( packagedArtifactFile.toPath() ).toMillis(); + long buildStartTime = session.getProjectBuildingRequest().getBuildStartTime().getTime(); + if ( artifactLastModified > buildStartTime ) + { + return true; + } + Iterator iterator = outputFiles.iterator(); while ( iterator.hasNext() ) { From 7291407c305a3842771f7bd8cd4ee4428c7c808f Mon Sep 17 00:00:00 2001 From: Martin Kanters Date: Tue, 31 Mar 2020 10:23:30 +0200 Subject: [PATCH 19/19] [MNG-4660] Fix potential nullpointer --- .../src/main/java/org/apache/maven/ReactorReader.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java index 846435bbca22..03463df3087c 100644 --- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java +++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java @@ -250,10 +250,13 @@ private boolean isPackagedArtifactUpToDate( MavenProject project, File packagedA // Not using File#lastModified() to avoid a Linux JDK8 milliseconds precision bug: JDK-8177809. long artifactLastModified = Files.getLastModifiedTime( packagedArtifactFile.toPath() ).toMillis(); - long buildStartTime = session.getProjectBuildingRequest().getBuildStartTime().getTime(); - if ( artifactLastModified > buildStartTime ) + if ( session.getProjectBuildingRequest().getBuildStartTime() != null ) { - return true; + long buildStartTime = session.getProjectBuildingRequest().getBuildStartTime().getTime(); + if ( artifactLastModified > buildStartTime ) + { + return true; + } } Iterator iterator = outputFiles.iterator();