[MNG-7487] Fix deadlock during forked lifecycle executions

# Conflicts:
#	maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java

# Conflicts:
#	maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java
This commit is contained in:
Guillaume Nodet 2022-05-12 10:04:51 +02:00
parent 6767f2500f
commit 2a276d0dcf
1 changed files with 23 additions and 14 deletions

View File

@ -85,6 +85,8 @@ public class MojoExecutor
private final Provider<MojosExecutionStrategy> mojosExecutionStrategy;
private final Map<Thread, MojoDescriptor> mojos = new ConcurrentHashMap<>();
@Inject
public MojoExecutor(
BuildPluginManager pluginManager,
@ -223,11 +225,8 @@ public class MojoExecutor
}
}
try ( ProjectLock lock = new ProjectLock( session, mojoDescriptor, aggregatorLock ) )
{
doExecute( session, mojoExecution, projectIndex, dependencyContext );
}
}
/**
* Aggregating mojo executions (possibly) modify all MavenProjects, including those that are currently in use
@ -237,13 +236,14 @@ public class MojoExecutor
* 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();
@ -271,6 +271,7 @@ public class MojoExecutor
{
acquiredAggregatorLock.unlock();
}
mojos.remove( Thread.currentThread() );
}
@SuppressWarnings( { "unchecked", "rawtypes" } )
@ -302,8 +303,23 @@ public class MojoExecutor
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
@ -324,13 +340,6 @@ public class MojoExecutor
throw e;
}
finally
{
for ( MavenProject forkedProject : forkedProjects )
{
forkedProject.setExecutionProject( null );
}
}
}
public void ensureDependenciesAreResolved( MojoDescriptor mojoDescriptor, MavenSession session,