From 0b79a9e64325f21659923fd01606b26d4c993b63 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Thu, 12 May 2022 10:04:51 +0200 Subject: [PATCH] [MNG-7487] Fix deadlock during forked lifecycle executions --- .../lifecycle/internal/MojoExecutor.java | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java index cf97c8cab954..beca2eff014c 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java @@ -85,6 +85,8 @@ public class MojoExecutor private final ReadWriteLock aggregatorLock = new ReentrantReadWriteLock(); + private final Map mojos = new ConcurrentHashMap<>(); + public MojoExecutor() { } @@ -206,10 +208,7 @@ private void execute( MavenSession session, MojoExecution mojoExecution, Project } } - try ( ProjectLock lock = new ProjectLock( session, mojoDescriptor, aggregatorLock ) ) - { - doExecute( session, mojoExecution, projectIndex, dependencyContext ); - } + doExecute( session, mojoExecution, projectIndex, dependencyContext ); } /** @@ -220,13 +219,14 @@ private void execute( MavenSession session, MojoExecution mojoExecution, Project * TODO: ideally, the builder should take care of the ordering in a smarter way * TODO: and concurrency issues fixed with MNG-7157 */ - private static class ProjectLock implements AutoCloseable + private class ProjectLock implements AutoCloseable { final Lock acquiredAggregatorLock; final Lock acquiredProjectLock; - ProjectLock( MavenSession session, MojoDescriptor mojoDescriptor, ReadWriteLock aggregatorLock ) + ProjectLock( MavenSession session, MojoDescriptor mojoDescriptor ) { + mojos.put( Thread.currentThread(), mojoDescriptor ); if ( session.getRequest().getDegreeOfConcurrency() > 1 ) { boolean aggregator = mojoDescriptor.isAggregator(); @@ -254,6 +254,7 @@ public void close() { acquiredAggregatorLock.unlock(); } + mojos.remove( Thread.currentThread() ); } @SuppressWarnings( { "unchecked", "rawtypes" } ) @@ -292,8 +293,23 @@ private void doExecute( MavenSession session, MojoExecution mojoExecution, Proje ensureDependenciesAreResolved( mojoDescriptor, session, dependencyContext ); - eventCatapult.fire( ExecutionEvent.Type.MojoStarted, session, mojoExecution ); + try ( ProjectLock lock = new ProjectLock( session, mojoDescriptor ) ) + { + doExecute2( session, mojoExecution ); + } + finally + { + for ( MavenProject forkedProject : forkedProjects ) + { + forkedProject.setExecutionProject( null ); + } + } + } + private void doExecute2( MavenSession session, MojoExecution mojoExecution ) + throws LifecycleExecutionException + { + eventCatapult.fire( ExecutionEvent.Type.MojoStarted, session, mojoExecution ); try { try @@ -314,13 +330,6 @@ private void doExecute( MavenSession session, MojoExecution mojoExecution, Proje throw e; } - finally - { - for ( MavenProject forkedProject : forkedProjects ) - { - forkedProject.setExecutionProject( null ); - } - } } public void ensureDependenciesAreResolved( MojoDescriptor mojoDescriptor, MavenSession session,