diff --git a/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java b/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java index 1eb2f86425..135b3e868e 100644 --- a/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java +++ b/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Set; import org.apache.maven.execution.MavenSession; +import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.lifecycle.LifecycleExecutor; import org.apache.maven.lifecycle.LifecycleNotFoundException; import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException; @@ -33,12 +34,8 @@ import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; import org.apache.maven.plugin.InvalidPluginDescriptorException; import org.apache.maven.plugin.MojoExecution; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.MojoNotFoundException; -import org.apache.maven.plugin.PluginConfigurationException; import org.apache.maven.plugin.PluginDescriptorParsingException; -import org.apache.maven.plugin.PluginManagerException; import org.apache.maven.plugin.PluginNotFoundException; import org.apache.maven.plugin.PluginResolutionException; import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; @@ -115,7 +112,7 @@ public class EmptyLifecycleExecutor } public List executeForkedExecutions( MojoExecution mojoExecution, MavenSession session ) - throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException + throws LifecycleExecutionException { return Collections.emptyList(); } diff --git a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java index 637726aedd..8b5badf92a 100644 --- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java +++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java @@ -175,6 +175,10 @@ public class DefaultMaven session.setProjects( projects ); + result.setTopologicallySortedProjects( session.getProjects() ); + + result.setProject( session.getTopLevelProject() ); + ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); try { @@ -224,6 +228,8 @@ public class DefaultMaven return processResult( result, e ); } + result.setTopologicallySortedProjects( session.getProjects() ); + // Desired order of precedence for local artifact repositories // // Reactor @@ -245,10 +251,6 @@ public class DefaultMaven return processResult( result, session.getResult().getExceptions().get( 0 ) ); } - result.setTopologicallySortedProjects( session.getProjects() ); - - result.setProject( session.getTopLevelProject() ); - return result; } diff --git a/maven-core/src/main/java/org/apache/maven/exception/DefaultExceptionHandler.java b/maven-core/src/main/java/org/apache/maven/exception/DefaultExceptionHandler.java index 48d8b404b2..82de097ee9 100644 --- a/maven-core/src/main/java/org/apache/maven/exception/DefaultExceptionHandler.java +++ b/maven-core/src/main/java/org/apache/maven/exception/DefaultExceptionHandler.java @@ -23,6 +23,7 @@ import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; +import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.model.building.ModelProblem; import org.apache.maven.plugin.AbstractMojoExecutionException; import org.apache.maven.plugin.MojoExecutionException; @@ -181,6 +182,10 @@ public class DefaultExceptionHandler reference = exception.getClass().getSimpleName(); } } + else if ( exception instanceof LifecycleExecutionException ) + { + reference = getReference( exception.getCause() ); + } else if ( !( exception instanceof RuntimeException ) ) { reference = exception.getClass().getSimpleName(); diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java index 602fecfa23..95b642f657 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java @@ -367,40 +367,51 @@ public class DefaultLifecycleExecutor private void resolveProjectDependencies( MavenProject project, Collection scopesToCollect, Collection scopesToResolve, MavenSession session, boolean aggregating ) - throws ArtifactResolutionException, ArtifactNotFoundException + throws LifecycleExecutionException { Set artifacts; try { - artifacts = projectDependenciesResolver.resolve( project, scopesToCollect, scopesToResolve, session ); - } - catch ( MultipleArtifactsNotFoundException e ) - { - /* - * MNG-2277, the check below compensates for our bad plugin support where we ended up with aggregator - * plugins that require dependency resolution although they usually run in phases of the build where project - * artifacts haven't been assembled yet. The prime example of this is "mvn release:prepare". - */ - if ( aggregating && areAllArtifactsInReactor( session.getProjects(), e.getMissingArtifacts() ) ) + try { - logger.warn( "The following artifacts could not be resolved at this point of the build" - + " but seem to be part of the reactor:" ); - - for ( Artifact artifact : e.getMissingArtifacts() ) + artifacts = projectDependenciesResolver.resolve( project, scopesToCollect, scopesToResolve, session ); + } + catch ( MultipleArtifactsNotFoundException e ) + { + /* + * MNG-2277, the check below compensates for our bad plugin support where we ended up with aggregator + * plugins that require dependency resolution although they usually run in phases of the build where project + * artifacts haven't been assembled yet. The prime example of this is "mvn release:prepare". + */ + if ( aggregating && areAllArtifactsInReactor( session.getProjects(), e.getMissingArtifacts() ) ) { - logger.warn( "o " + artifact.getId() ); + logger.warn( "The following artifacts could not be resolved at this point of the build" + + " but seem to be part of the reactor:" ); + + for ( Artifact artifact : e.getMissingArtifacts() ) + { + logger.warn( "o " + artifact.getId() ); + } + + logger.warn( "Try running the build up to the lifecycle phase \"package\"" ); + + artifacts = new LinkedHashSet( e.getResolvedArtifacts() ); + } + else + { + throw e; } - - logger.warn( "Try running the build up to the lifecycle phase \"package\"" ); - - artifacts = new LinkedHashSet( e.getResolvedArtifacts() ); - } - else - { - throw e; } } + catch ( ArtifactResolutionException e ) + { + throw new LifecycleExecutionException( null, project, e ); + } + catch ( ArtifactNotFoundException e ) + { + throw new LifecycleExecutionException( null, project, e ); + } project.setArtifacts( artifacts ); @@ -488,7 +499,7 @@ public class DefaultLifecycleExecutor } void checkForUpdate( MavenSession session ) - throws ArtifactResolutionException, ArtifactNotFoundException + throws LifecycleExecutionException { if ( lastProject == session.getCurrentProject() ) { @@ -509,23 +520,25 @@ public class DefaultLifecycleExecutor private void execute( MavenSession session, MojoExecution mojoExecution, ProjectIndex projectIndex, DependencyContext dependencyContext ) - throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException, - ArtifactResolutionException, ArtifactNotFoundException + throws LifecycleExecutionException { MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); if ( mojoDescriptor.isProjectRequired() && !session.isUsingPOMsFromFilesystem() ) { - throw new MojoExecutionException( "Goal " + mojoDescriptor.getId() - + " requires a project to execute but there is no POM in this build." ); + Throwable cause = + new IllegalStateException( "Goal requires a project to execute but there is no POM in this build." ); + throw new LifecycleExecutionException( mojoExecution, null, cause ); } if ( mojoDescriptor.isOnlineRequired() && session.isOffline() ) { if ( MojoExecution.Source.CLI.equals( mojoExecution.getSource() ) ) { - throw new MojoExecutionException( "Goal " + mojoDescriptor.getId() - + " requires online mode for execution but Maven is currently offline." ); + Throwable cause = + new IllegalStateException( "Goal requires online mode for execution" + + " but Maven is currently offline." ); + throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), cause ); } else { @@ -544,29 +557,30 @@ public class DefaultLifecycleExecutor try { - pluginManager.executeMojo( session, mojoExecution ); + try + { + pluginManager.executeMojo( session, mojoExecution ); + } + catch ( MojoFailureException e ) + { + throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e ); + } + catch ( MojoExecutionException e ) + { + throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e ); + } + catch ( PluginConfigurationException e ) + { + throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e ); + } + catch ( PluginManagerException e ) + { + throw new LifecycleExecutionException( mojoExecution, session.getCurrentProject(), e ); + } fireEvent( session, mojoExecution, LifecycleEventCatapult.MOJO_SUCCEEDED ); } - catch ( MojoFailureException e ) - { - fireEvent( session, mojoExecution, LifecycleEventCatapult.MOJO_FAILED ); - - throw e; - } - catch ( MojoExecutionException e ) - { - fireEvent( session, mojoExecution, LifecycleEventCatapult.MOJO_FAILED ); - - throw e; - } - catch ( PluginConfigurationException e ) - { - fireEvent( session, mojoExecution, LifecycleEventCatapult.MOJO_FAILED ); - - throw e; - } - catch ( PluginManagerException e ) + catch ( LifecycleExecutionException e ) { fireEvent( session, mojoExecution, LifecycleEventCatapult.MOJO_FAILED ); @@ -582,8 +596,7 @@ public class DefaultLifecycleExecutor } public List executeForkedExecutions( MojoExecution mojoExecution, MavenSession session ) - throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException, - ArtifactResolutionException, ArtifactNotFoundException + throws LifecycleExecutionException { return executeForkedExecutions( mojoExecution, session, new ProjectIndex( session.getProjects() ), new DependencyContext( mojoExecution ) ); @@ -591,8 +604,7 @@ public class DefaultLifecycleExecutor private List executeForkedExecutions( MojoExecution mojoExecution, MavenSession session, ProjectIndex projectIndex, DependencyContext dependencyContext ) - throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException, - ArtifactResolutionException, ArtifactNotFoundException + throws LifecycleExecutionException { List forkedProjects = Collections.emptyList(); @@ -643,25 +655,7 @@ public class DefaultLifecycleExecutor fireEvent( session, mojoExecution, LifecycleEventCatapult.FORK_SUCCEEDED ); } - catch ( MojoFailureException e ) - { - fireEvent( session, mojoExecution, LifecycleEventCatapult.FORK_FAILED ); - - throw e; - } - catch ( MojoExecutionException e ) - { - fireEvent( session, mojoExecution, LifecycleEventCatapult.FORK_FAILED ); - - throw e; - } - catch ( PluginConfigurationException e ) - { - fireEvent( session, mojoExecution, LifecycleEventCatapult.FORK_FAILED ); - - throw e; - } - catch ( PluginManagerException e ) + catch ( LifecycleExecutionException e ) { fireEvent( session, mojoExecution, LifecycleEventCatapult.FORK_FAILED ); diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java index 2c18021154..f4504f3016 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java @@ -1,7 +1,5 @@ package org.apache.maven.lifecycle; -import org.apache.maven.project.MavenProject; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -21,6 +19,9 @@ import org.apache.maven.project.MavenProject; * under the License. */ +import org.apache.maven.plugin.MojoExecution; +import org.apache.maven.project.MavenProject; + /** * @author Jason van Zyl * @version $Id$ @@ -50,9 +51,62 @@ public class LifecycleExecutionException super( message ); this.project = project; } - + + LifecycleExecutionException( String message, MojoExecution execution, MavenProject project ) + { + super( message ); + this.project = project; + } + + LifecycleExecutionException( String message, MojoExecution execution, MavenProject project, Throwable cause ) + { + super( message, cause ); + this.project = project; + } + + LifecycleExecutionException( MojoExecution execution, MavenProject project, Throwable cause ) + { + this( createMessage( execution, project, cause ), execution, project, cause ); + } + public MavenProject getProject() { return project; } + + private static String createMessage( MojoExecution execution, MavenProject project, Throwable cause ) + { + StringBuilder buffer = new StringBuilder( 256 ); + + buffer.append( "Failed to execute goal" ); + + if ( execution != null ) + { + buffer.append( ' ' ); + buffer.append( execution.getGroupId() ); + buffer.append( ':' ); + buffer.append( execution.getArtifactId() ); + buffer.append( ':' ); + buffer.append( execution.getVersion() ); + buffer.append( ':' ); + buffer.append( execution.getGoal() ); + buffer.append( " (" ); + buffer.append( execution.getExecutionId() ); + buffer.append( ")" ); + } + + if ( project != null ) + { + buffer.append( " on project " ); + buffer.append( project.getArtifactId() ); + } + + if ( cause != null ) + { + buffer.append( ": " ).append( cause.getMessage() ); + } + + return buffer.toString(); + } + } diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java index 0710cbcd41..e326865cc7 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java @@ -22,16 +22,11 @@ package org.apache.maven.lifecycle; import java.util.List; import java.util.Set; -import org.apache.maven.artifact.resolver.ArtifactNotFoundException; -import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.InvalidPluginDescriptorException; import org.apache.maven.plugin.MojoExecution; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.MojoNotFoundException; -import org.apache.maven.plugin.PluginConfigurationException; import org.apache.maven.plugin.PluginDescriptorParsingException; import org.apache.maven.plugin.PluginManagerException; import org.apache.maven.plugin.PluginNotFoundException; @@ -109,7 +104,6 @@ public interface LifecycleExecutor * will never be {@code null}. */ List executeForkedExecutions( MojoExecution mojoExecution, MavenSession session ) - throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException, - ArtifactResolutionException, ArtifactNotFoundException; + throws LifecycleExecutionException; } diff --git a/maven-core/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java b/maven-core/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java index 1eb2f86425..135b3e868e 100644 --- a/maven-core/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java +++ b/maven-core/src/test/java/org/apache/maven/project/EmptyLifecycleExecutor.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Set; import org.apache.maven.execution.MavenSession; +import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.lifecycle.LifecycleExecutor; import org.apache.maven.lifecycle.LifecycleNotFoundException; import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException; @@ -33,12 +34,8 @@ import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; import org.apache.maven.plugin.InvalidPluginDescriptorException; import org.apache.maven.plugin.MojoExecution; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.MojoNotFoundException; -import org.apache.maven.plugin.PluginConfigurationException; import org.apache.maven.plugin.PluginDescriptorParsingException; -import org.apache.maven.plugin.PluginManagerException; import org.apache.maven.plugin.PluginNotFoundException; import org.apache.maven.plugin.PluginResolutionException; import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; @@ -115,7 +112,7 @@ public class EmptyLifecycleExecutor } public List executeForkedExecutions( MojoExecution mojoExecution, MavenSession session ) - throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException + throws LifecycleExecutionException { return Collections.emptyList(); } diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index 9a4eabecba..e717c3dbc4 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -38,7 +38,9 @@ import org.apache.maven.execution.DefaultMavenExecutionRequest; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionRequestPopulator; import org.apache.maven.execution.MavenExecutionResult; +import org.apache.maven.lifecycle.LifecycleExecutionException; import org.apache.maven.model.building.ModelProcessor; +import org.apache.maven.project.MavenProject; import org.apache.maven.repository.ArtifactTransferListener; import org.apache.maven.settings.building.DefaultSettingsBuildingRequest; import org.apache.maven.settings.building.SettingsBuilder; @@ -426,11 +428,18 @@ public class MavenCli Map references = new LinkedHashMap(); + MavenProject project = null; + for ( Throwable exception : result.getExceptions() ) { ExceptionSummary summary = handler.handleException( exception ); logSummary( summary, references, "", cliRequest.showErrors ); + + if ( project == null && exception instanceof LifecycleExecutionException ) + { + project = ( (LifecycleExecutionException) exception ).getProject(); + } } logger.error( "" ); @@ -455,6 +464,13 @@ public class MavenCli } } + if ( project != null && !project.equals( result.getTopologicallySortedProjects().get( 0 ) ) ) + { + logger.error( "" ); + logger.error( "After correcting the problems, you can resume the build with the command" ); + logger.error( " mvn -rf :" + project.getArtifactId() ); + } + if ( MavenExecutionRequest.REACTOR_FAIL_NEVER.equals( cliRequest.request.getReactorFailureBehavior() ) ) { logger.info( "Build failures were ignored." );