diff --git a/maven-core/src/main/aspect/org/apache/maven/errors/AbstractCoreReporterManagerAspect.aj b/maven-core/src/main/aspect/org/apache/maven/errors/AbstractCoreReporterManagerAspect.aj new file mode 100644 index 0000000000..77faa5e477 --- /dev/null +++ b/maven-core/src/main/aspect/org/apache/maven/errors/AbstractCoreReporterManagerAspect.aj @@ -0,0 +1,23 @@ +package org.apache.maven.errors; + +public abstract aspect AbstractCoreReporterManagerAspect +{ + + private CoreErrorReporter reporter; + + public void setCoreErrorReporter( CoreErrorReporter reporter ) + { + this.reporter = reporter; + } + + protected CoreErrorReporter getReporter() + { + if ( reporter == null ) + { + reporter = new DefaultCoreErrorReporter(); + } + + return reporter; + } + +} diff --git a/maven-core/src/main/aspect/org/apache/maven/errors/BuildFailureReporterAspect.aj b/maven-core/src/main/aspect/org/apache/maven/errors/BuildFailureReporterAspect.aj new file mode 100644 index 0000000000..70e005ab08 --- /dev/null +++ b/maven-core/src/main/aspect/org/apache/maven/errors/BuildFailureReporterAspect.aj @@ -0,0 +1,99 @@ +package org.apache.maven.errors; + +import org.apache.maven.project.MavenProject; +import org.apache.maven.lifecycle.TaskValidationResult; +import org.apache.maven.lifecycle.LifecycleLoaderException; +import org.apache.maven.lifecycle.LifecycleSpecificationException; +import org.apache.maven.plugin.loader.PluginLoaderException; +import org.apache.maven.ProjectCycleException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.lifecycle.model.MojoBinding; +import org.apache.maven.lifecycle.LifecycleExecutor; +import org.apache.maven.NoGoalsSpecifiedException; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.execution.ReactorManager; +import org.apache.maven.AggregatedBuildFailureException; +import org.apache.maven.ProjectBuildFailureException; +import org.apache.maven.Maven; + +public aspect BuildFailureReporterAspect + extends AbstractCoreReporterManagerAspect +{ + + private pointcut le_execute( MavenSession session, ReactorManager reactorManager ): + execution( void LifecycleExecutor+.execute( MavenSession, ReactorManager, .. ) ) + && args( session, reactorManager, .. ); + + after( ReactorManager reactorManager, NoGoalsSpecifiedException err ): + cflow( le_execute( MavenSession, reactorManager ) ) + && execution( NoGoalsSpecifiedException.new( .. ) ) + && this( err ) + { + getReporter().reportNoGoalsSpecifiedException( reactorManager.getTopLevelProject(), err ); + } + + private pointcut aggregatedBuildFailureException_ctor( MojoBinding binding, MojoFailureException cause ): + execution( AggregatedBuildFailureException.new( .., MojoBinding, MojoFailureException ) ) + && args( .., binding, cause ); + + after( MavenSession session, MojoBinding binding, MojoFailureException cause ): + cflow( le_execute( session, ReactorManager ) ) + && aggregatedBuildFailureException_ctor( binding, cause ) + { + getReporter().reportAggregatedMojoFailureException( session, binding, cause ); + } + + private pointcut projectBuildFailureException_ctor( MojoBinding binding, MojoFailureException cause ): + execution( ProjectBuildFailureException.new( .., MojoBinding, MojoFailureException ) ) + && args( .., binding, cause ); + + after( MavenSession session, MojoBinding binding, MojoFailureException cause ): + cflow( le_execute( session, ReactorManager ) ) + && projectBuildFailureException_ctor( binding, cause ) + { + getReporter().reportProjectMojoFailureException( session, binding, cause ); + } + + private pointcut mvn_createReactorManager(): + execution( ReactorManager Maven+.createReactorManager( .. ) ); + + after( ProjectCycleException err ): + cflow( mvn_createReactorManager() ) + && execution( ProjectCycleException.new( .. ) ) + && this( err ) + { + getReporter().reportProjectCycle( err ); + } + + private pointcut le_isTaskValid( MavenSession session, MavenProject rootProject ): + execution( TaskValidationResult LifecycleExecutor+.isTaskValid( .., MavenSession, MavenProject ) ) + && args( .., session, rootProject ); + + before( MavenSession session, MavenProject rootProject, PluginLoaderException cause, TaskValidationResult result ): + cflow( le_isTaskValid( session, rootProject ) ) + && execution( TaskValidationResult.new( .., PluginLoaderException ) ) + && args( .., cause ) + && this( result ) + { + getReporter().reportPluginErrorWhileValidatingTask( session, rootProject, cause, result ); + } + + before( MavenSession session, MavenProject rootProject, LifecycleSpecificationException cause, TaskValidationResult result ): + cflow( le_isTaskValid( session, rootProject ) ) + && execution( TaskValidationResult.new( .., LifecycleSpecificationException ) ) + && args( .., cause ) + && this( result ) + { + getReporter().reportLifecycleSpecErrorWhileValidatingTask( session, rootProject, cause, result ); + } + + before( MavenSession session, MavenProject rootProject, LifecycleLoaderException cause, TaskValidationResult result ): + cflow( le_isTaskValid( session, rootProject ) ) + && execution( TaskValidationResult.new( .., LifecycleLoaderException ) ) + && args( .., cause ) + && this( result ) + { + getReporter().reportLifecycleLoaderErrorWhileValidatingTask( session, rootProject, cause, result ); + } + +} diff --git a/maven-core/src/main/aspect/org/apache/maven/errors/CoreReporterManagerAspect.aj b/maven-core/src/main/aspect/org/apache/maven/errors/CoreReporterManagerAspect.aj new file mode 100644 index 0000000000..4c37c50160 --- /dev/null +++ b/maven-core/src/main/aspect/org/apache/maven/errors/CoreReporterManagerAspect.aj @@ -0,0 +1,14 @@ +package org.apache.maven.errors; + +import org.aspectj.lang.Aspects; + +public aspect CoreReporterManagerAspect +{ + + public void setReporter( CoreErrorReporter reporter ) + { + BuildFailureReporterAspect buildFailureReporterAspect = (BuildFailureReporterAspect) Aspects.aspectOf( BuildFailureReporterAspect.class ); + buildFailureReporterAspect.setCoreErrorReporter( reporter ); + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/errors/CoreErrorReporter.java b/maven-core/src/main/java/org/apache/maven/errors/CoreErrorReporter.java new file mode 100644 index 0000000000..8c522506f5 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/errors/CoreErrorReporter.java @@ -0,0 +1,41 @@ +package org.apache.maven.errors; + +import org.apache.maven.NoGoalsSpecifiedException; +import org.apache.maven.ProjectCycleException; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.lifecycle.LifecycleLoaderException; +import org.apache.maven.lifecycle.LifecycleSpecificationException; +import org.apache.maven.lifecycle.TaskValidationResult; +import org.apache.maven.lifecycle.model.MojoBinding; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.loader.PluginLoaderException; +import org.apache.maven.project.MavenProject; + +public interface CoreErrorReporter +{ + + String NEWLINE = "\n"; + + void clearErrors(); + + String getFormattedMessage( Throwable error ); + + Throwable getRealCause( Throwable error ); + + Throwable findReportedException( Throwable error ); + + void reportNoGoalsSpecifiedException( MavenProject rootProject, NoGoalsSpecifiedException error ); + + void reportAggregatedMojoFailureException( MavenSession session, MojoBinding binding, MojoFailureException cause ); + + void reportProjectMojoFailureException( MavenSession session, MojoBinding binding, MojoFailureException cause ); + + void reportProjectCycle( ProjectCycleException error ); + + void reportPluginErrorWhileValidatingTask( MavenSession session, MavenProject rootProject, PluginLoaderException cause, TaskValidationResult result ); + + void reportLifecycleSpecErrorWhileValidatingTask( MavenSession session, MavenProject rootProject, LifecycleSpecificationException cause, TaskValidationResult result ); + + void reportLifecycleLoaderErrorWhileValidatingTask( MavenSession session, MavenProject rootProject, LifecycleLoaderException cause, TaskValidationResult result ); + +} diff --git a/maven-core/src/main/java/org/apache/maven/errors/CoreErrorTips.java b/maven-core/src/main/java/org/apache/maven/errors/CoreErrorTips.java new file mode 100644 index 0000000000..6f5672a2dc --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/errors/CoreErrorTips.java @@ -0,0 +1,52 @@ +package org.apache.maven.errors; + +import org.apache.maven.ProjectCycleException; +import org.apache.maven.lifecycle.TaskValidationResult; +import org.apache.maven.lifecycle.model.MojoBinding; + +import java.util.Arrays; +import java.util.List; + +// NOTE: The strange String[] syntax is a backward adaptation from java5 stuff, where +// I was using varargs in listOf(..). I'm not moving them to constants because I'd like +// to go back to this someday... + +// TODO: Optimize the String[] instances in here to List constants, and remove listOf(..) +public final class CoreErrorTips +{ + + private static final List NO_GOALS_TIPS = Arrays.asList( new String[] { + "Maven in 5 Minutes guide (http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html)", + "Maven User's documentation (http://maven.apache.org/users/)", + "Maven Plugins page (http://maven.apache.org/plugins/)", + "CodeHaus Mojos Project page (http://mojo.codehaus.org/plugins.html)" + } ); + + private CoreErrorTips() + { + } + + public static List getNoGoalsTips() + { + return NO_GOALS_TIPS; + } + + public static List getMojoFailureTips( MojoBinding binding ) + { + // TODO Auto-generated method stub + return null; + } + + public static List getProjectCycleTips( ProjectCycleException error ) + { + // TODO Auto-generated method stub + return null; + } + + public static List getTaskValidationTips( TaskValidationResult result, Exception cause ) + { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/maven-core/src/main/java/org/apache/maven/errors/DefaultCoreErrorReporter.java b/maven-core/src/main/java/org/apache/maven/errors/DefaultCoreErrorReporter.java new file mode 100644 index 0000000000..c9ff1fa838 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/errors/DefaultCoreErrorReporter.java @@ -0,0 +1,327 @@ +package org.apache.maven.errors; + +import org.apache.maven.NoGoalsSpecifiedException; +import org.apache.maven.ProjectCycleException; +import org.apache.maven.artifact.ArtifactUtils; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.lifecycle.LifecycleLoaderException; +import org.apache.maven.lifecycle.LifecycleSpecificationException; +import org.apache.maven.lifecycle.MojoBindingUtils; +import org.apache.maven.lifecycle.TaskValidationResult; +import org.apache.maven.lifecycle.model.MojoBinding; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.loader.PluginLoaderException; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.dag.CycleDetectedException; + +import java.io.StringWriter; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class DefaultCoreErrorReporter + implements CoreErrorReporter +{ + + private Map formattedMessages = new HashMap(); + + private Map realCauses = new HashMap(); + + /** + * @see org.apache.maven.project.error.ProjectErrorReporter#clearErrors() + */ + public void clearErrors() + { + formattedMessages.clear(); + realCauses.clear(); + } + + /** + * @see org.apache.maven.project.error.ProjectErrorReporter#hasInformationFor(java.lang.Throwable) + */ + public Throwable findReportedException( Throwable error ) + { + if ( formattedMessages.containsKey( error ) ) + { + return error; + } + else if ( error.getCause() != null ) + { + return findReportedException( error.getCause() ); + } + + return null; + } + + /** + * @see org.apache.maven.project.error.ProjectErrorReporter#getFormattedMessage(java.lang.Throwable) + */ + public String getFormattedMessage( Throwable error ) + { + return (String) formattedMessages.get( error ); + } + + /** + * @see org.apache.maven.project.error.ProjectErrorReporter#getRealCause(java.lang.Throwable) + */ + public Throwable getRealCause( Throwable error ) + { + return (Throwable) realCauses.get( error ); + } + + private void registerBuildError( Throwable error, + String formattedMessage, + Throwable realCause ) + { + formattedMessages.put( error, formattedMessage ); + if ( realCause != null ) + { + realCauses.put( error, realCause ); + } + } + + private void registerBuildError( Throwable error, + String formattedMessage ) + { + formattedMessages.put( error, formattedMessage ); + } + + public void reportNoGoalsSpecifiedException( MavenProject rootProject, NoGoalsSpecifiedException error ) + { + StringWriter writer = new StringWriter(); + + writer.write( NEWLINE ); + writer.write( "You have not specified any goals or lifecycle phases for Maven to execute." ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + writer.write( "Either specify a goal or lifecycle phase on the command line" ); + writer.write( NEWLINE ); + writer.write( "(you may want to try \'package\' to get started), or configure the " ); + writer.write( NEWLINE ); + writer.write( " element in the build section of your project POM." ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + writer.write( "NOTE: You can also chain multiple goals/phases together, as in the following example:" ); + writer.write( NEWLINE ); + writer.write( "mvn clean package" ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + + addTips( CoreErrorTips.getNoGoalsTips(), writer ); + + registerBuildError( error, writer.toString() ); + } + + private void addTips( List tips, + StringWriter writer ) + { + if ( ( tips != null ) && !tips.isEmpty() ) + { + writer.write( NEWLINE ); + writer.write( NEWLINE ); + writer.write( "Some tips:" ); + for ( Iterator it = tips.iterator(); it.hasNext(); ) + { + String tip = (String) it.next(); + + writer.write( NEWLINE ); + writer.write( "\t- " ); + writer.write( tip ); + } + } + } + + public void reportAggregatedMojoFailureException( MavenSession session, + MojoBinding binding, + MojoFailureException cause ) + { + StringWriter writer = new StringWriter(); + + writer.write( NEWLINE ); + writer.write( "Mojo (aggregator): " ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + writer.write( " " ); + writer.write( MojoBindingUtils.toString( binding ) ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + writer.write( "FAILED while executing in directory:" ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + writer.write( " " ); + writer.write( session.getExecutionRootDirectory() ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + writer.write( "Reason:" ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + + handleMojoFailureException( cause, writer ); + + addTips( CoreErrorTips.getMojoFailureTips( binding ), writer ); + + registerBuildError( cause, writer.toString(), cause.getCause() ); + } + + public void reportProjectMojoFailureException( MavenSession session, + MojoBinding binding, + MojoFailureException cause ) + { + StringWriter writer = new StringWriter(); + + writer.write( NEWLINE ); + writer.write( "Mojo: " ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + writer.write( " " ); + writer.write( MojoBindingUtils.toString( binding ) ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + writer.write( "FAILED for project: " ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + writer.write( " " ); + writer.write( session.getCurrentProject().getId() ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + writer.write( "Reason:" ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + + handleMojoFailureException( cause, writer ); + + addTips( CoreErrorTips.getMojoFailureTips( binding ), writer ); + + registerBuildError( cause, writer.toString(), cause.getCause() ); + } + + private void handleMojoFailureException( MojoFailureException error, + StringWriter writer ) + { + String message = error.getLongMessage(); + if ( message == null ) + { + message = error.getMessage(); + } + + writer.write( message ); + writer.write( NEWLINE ); + } + + public void reportProjectCycle( ProjectCycleException error ) + { + StringWriter writer = new StringWriter(); + + writer.write( NEWLINE ); + writer.write( "Maven has detected a cyclic relationship among a set of projects in the current build." ); + writer.write( NEWLINE ); + writer.write( "The projects involved are:" ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + + List projects = error.getProjects(); + Map projectsByVersionlessId = new HashMap(); + for ( Iterator it = projects.iterator(); it.hasNext(); ) + { + MavenProject project = (MavenProject) it.next(); + projectsByVersionlessId.put( ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() ), project ); + } + + CycleDetectedException cause = (CycleDetectedException) error.getCause(); + List cycle = cause.getCycle(); + for ( Iterator it = cycle.iterator(); it.hasNext(); ) + { + String id = (String) it.next(); + MavenProject project = (MavenProject) projectsByVersionlessId.get( id ); + + writer.write( "- " ); + writer.write( project.getId() ); + writer.write( " (path: " ); + writer.write( project.getFile().getPath() ); + writer.write( ")" ); + writer.write( NEWLINE ); + } + + writer.write( NEWLINE ); + writer.write( "NOTE: This cycle usually indicates two projects listing one another as dependencies, but" ); + writer.write( NEWLINE ); + writer.write( "may also indicate one project using another as a parent, plugin, or extension." ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + + addTips( CoreErrorTips.getProjectCycleTips( error ), writer ); + + registerBuildError( error, writer.toString(), cause ); + } + + public void reportLifecycleLoaderErrorWhileValidatingTask( MavenSession session, + MavenProject rootProject, + LifecycleLoaderException cause, + TaskValidationResult result ) + { + StringWriter writer = new StringWriter(); + + writer.write( NEWLINE ); + writer.write( "Invalid mojo or lifecycle phase: " ); + writer.write( result.getInvalidTask() ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + + writer.write( "Original error message was: " ); + writer.write( cause.getMessage() ); + + addTips( CoreErrorTips.getTaskValidationTips( result, cause ), writer ); + + registerBuildError( cause, writer.toString(), cause.getCause() ); + } + + public void reportLifecycleSpecErrorWhileValidatingTask( MavenSession session, + MavenProject rootProject, + LifecycleSpecificationException cause, + TaskValidationResult result ) + { + StringWriter writer = new StringWriter(); + + writer.write( NEWLINE ); + writer.write( "Invalid mojo or lifecycle phase: " ); + writer.write( result.getInvalidTask() ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + + writer.write( "Original error message was: " ); + writer.write( cause.getMessage() ); + + addTips( CoreErrorTips.getTaskValidationTips( result, cause ), writer ); + + registerBuildError( cause, writer.toString(), cause.getCause() ); + } + + public void reportPluginErrorWhileValidatingTask( MavenSession session, + MavenProject rootProject, + PluginLoaderException cause, + TaskValidationResult result ) + { + StringWriter writer = new StringWriter(); + + writer.write( NEWLINE ); + writer.write( "Invalid mojo or lifecycle phase: " ); + writer.write( result.getInvalidTask() ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + + writer.write( "Failed to load plugin: " ); + writer.write( cause.getPluginKey() ); + writer.write( NEWLINE ); + writer.write( NEWLINE ); + + writer.write( "Original error message was: " ); + writer.write( cause.getMessage() ); + + addTips( CoreErrorTips.getTaskValidationTips( result, cause ), writer ); + + registerBuildError( cause, writer.toString(), cause.getCause() ); + } +} diff --git a/maven-embedder/src/main/aspect/org/apache/maven/embedder/cache/ErrorReportingAspect.aj b/maven-embedder/src/main/aspect/org/apache/maven/embedder/cache/ErrorReportingAspect.aj index 2d65b8b979..0f2e31a68e 100644 --- a/maven-embedder/src/main/aspect/org/apache/maven/embedder/cache/ErrorReportingAspect.aj +++ b/maven-embedder/src/main/aspect/org/apache/maven/embedder/cache/ErrorReportingAspect.aj @@ -5,8 +5,12 @@ import org.aspectj.lang.Aspects; import java.io.StringWriter; import java.io.PrintWriter; +import org.apache.maven.BuildFailureException; import org.apache.maven.cli.CLIReportingUtils; import org.apache.maven.embedder.MavenEmbedder; +import org.apache.maven.errors.CoreErrorReporter; +import org.apache.maven.errors.CoreReporterManagerAspect; +import org.apache.maven.errors.DefaultCoreErrorReporter; import org.apache.maven.execution.MavenExecutionResult; import org.apache.maven.project.aspect.ProjectReporterManagerAspect; import org.apache.maven.project.error.DefaultProjectErrorReporter; @@ -18,9 +22,12 @@ public privileged aspect ErrorReportingAspect private ProjectErrorReporter projectErrorReporter; + private CoreErrorReporter coreErrorReporter; + private pointcut embedderCalls(): execution( public MavenExecutionResult MavenEmbedder.*( .. ) ); + // TODO: Use MavenExecutionRequest to allow configuration of the reporters to be used. before(): embedderCalls() && !cflow( embedderCalls() ) { @@ -28,32 +35,23 @@ public privileged aspect ErrorReportingAspect ProjectReporterManagerAspect prma = (ProjectReporterManagerAspect) Aspects.aspectOf( ProjectReporterManagerAspect.class ); prma.setReporter( projectErrorReporter ); - } - private pointcut cliReportingUtilsCalls(): - execution( * CLIReportingUtils.*( .. ) ); + coreErrorReporter = new DefaultCoreErrorReporter(); - before(): - cliReportingUtilsCalls() - && !cflow( cliReportingUtilsCalls() ) - && !cflow( embedderCalls() ) - { - projectErrorReporter = new DefaultProjectErrorReporter(); - - ProjectReporterManagerAspect prma = (ProjectReporterManagerAspect) Aspects.aspectOf( ProjectReporterManagerAspect.class ); - prma.setReporter( projectErrorReporter ); + CoreReporterManagerAspect crma = (CoreReporterManagerAspect) Aspects.aspectOf( CoreReporterManagerAspect.class ); + crma.setReporter( coreErrorReporter ); } boolean around( ProjectBuildingException e, boolean showStackTraces, StringWriter writer ): execution( private static boolean CLIReportingUtils.handleProjectBuildingException( ProjectBuildingException, boolean, StringWriter ) ) && args( e, showStackTraces, writer ) { -// if ( projectErrorReporter == null ) -// { -// return proceed( e, showStackTraces, writer ); -// } -// else -// { + if ( projectErrorReporter == null ) + { + return proceed( e, showStackTraces, writer ); + } + else + { Throwable reportingError = projectErrorReporter.findReportedException( e ); boolean result = false; @@ -81,7 +79,47 @@ public privileged aspect ErrorReportingAspect } return result; -// } + } + } + + boolean around( BuildFailureException e, boolean showStackTraces, StringWriter writer ): + execution( private static boolean CLIReportingUtils.handleBuildFailureException( BuildFailureException, boolean, StringWriter ) ) + && args( e, showStackTraces, writer ) + { + if ( coreErrorReporter == null ) + { + return proceed( e, showStackTraces, writer ); + } + else + { + Throwable reportingError = coreErrorReporter.findReportedException( e ); + + boolean result = false; + + if ( reportingError != null ) + { + writer.write( coreErrorReporter.getFormattedMessage( reportingError ) ); + + if ( showStackTraces ) + { + writer.write( CLIReportingUtils.NEWLINE ); + writer.write( CLIReportingUtils.NEWLINE ); + Throwable cause = coreErrorReporter.getRealCause( reportingError ); + cause.printStackTrace( new PrintWriter( writer ) ); + } + + writer.write( CLIReportingUtils.NEWLINE ); + writer.write( CLIReportingUtils.NEWLINE ); + + result = true; + } + else + { + result = proceed( e, showStackTraces, writer ); + } + + return result; + } } } diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/CLIReportingUtils.java b/maven-embedder/src/main/java/org/apache/maven/cli/CLIReportingUtils.java index a9a846a47a..7c9da4067d 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/CLIReportingUtils.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/CLIReportingUtils.java @@ -1,11 +1,6 @@ package org.apache.maven.cli; -import org.apache.maven.AggregatedBuildFailureException; import org.apache.maven.BuildFailureException; -import org.apache.maven.InvalidTaskException; -import org.apache.maven.NoGoalsSpecifiedException; -import org.apache.maven.ProjectBuildFailureException; -import org.apache.maven.ProjectCycleException; import org.apache.maven.artifact.resolver.ArtifactNotFoundException; import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.embedder.MavenEmbedderConsoleLogger; @@ -16,11 +11,8 @@ import org.apache.maven.execution.MavenExecutionResult; import org.apache.maven.execution.ReactorManager; import org.apache.maven.extension.ExtensionScanningException; import org.apache.maven.lifecycle.LifecycleExecutionException; -import org.apache.maven.lifecycle.MojoBindingUtils; import org.apache.maven.model.Plugin; -import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.PluginNotFoundException; -import org.apache.maven.plugin.loader.PluginLoaderException; import org.apache.maven.plugin.version.PluginVersionNotFoundException; import org.apache.maven.plugin.version.PluginVersionResolutionException; import org.apache.maven.project.DuplicateProjectException; @@ -37,7 +29,6 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; -import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.TimeZone; @@ -566,192 +557,11 @@ public final class CLIReportingUtils return result; } + // NOTE: This method is an aspect target. private static boolean handleProjectBuildingException( ProjectBuildingException e, boolean showStackTraces, StringWriter writer ) { - // ===================================================================== - // Cases covered: - // ===================================================================== - // - // ProjectBuildingException(String, String, File, XmlPullParserException) - // - // ProjectBuildingException(String, String, IOException) - // ProjectBuildingException(String, String, File, IOException) - // - // ProjectBuildingException(String, String, ArtifactNotFoundException) - // ProjectBuildingException(String, String, File, ArtifactNotFoundException) - // - // ProjectBuildingException(String, String, ArtifactResolutionException) - // ProjectBuildingException(String, String, File, ArtifactResolutionException) - // - // ProjectBuildingException(String, String, File, ProfileActivationException) - // - // ProjectBuildingException(String, String, InvalidRepositoryException) - // ProjectBuildingException(String, String, File, InvalidRepositoryException) - // - // ===================================================================== - // Subclass cases: - // ===================================================================== - // - // InvalidProjectModelException(all) - // InvalidProjectVersionException(all) - // InvalidDependencyVersionException(all) - - // Start by looking at whether we can handle the PBE as a specific sub-class of ProjectBuildingException... -// if ( e instanceof InvalidProjectModelException ) -// { -// InvalidProjectModelException error = (InvalidProjectModelException) e; -// -// writer.write( error.getMessage() ); -// writer.write( NEWLINE ); -// writer.write( NEWLINE ); -// writer.write( "The following POM validation errors were detected:" ); -// writer.write( NEWLINE ); -// -// for ( Iterator it = error.getValidationResult().getMessages().iterator(); it.hasNext(); ) -// { -// String message = (String) it.next(); -// writer.write( NEWLINE ); -// writer.write( " - " ); -// writer.write( message ); -// } -// -// writer.write( NEWLINE ); -// writer.write( NEWLINE ); -// -// result = true; -// } -// else if ( e instanceof InvalidDependencyVersionException ) -// { -// writer.write( NEWLINE ); -// writer.write( "Your project declares a dependency with an invalid version." ); -// writer.write( NEWLINE ); -// writer.write( NEWLINE ); -// -// Dependency dep = ((InvalidDependencyVersionException)e).getDependency(); -// writer.write( "Dependency:" ); -// writer.write( NEWLINE ); -// writer.write( "Group-Id: " ); -// writer.write( dep.getGroupId() ); -// writer.write( NEWLINE ); -// writer.write( "Artifact-Id: " ); -// writer.write( dep.getArtifactId() ); -// writer.write( NEWLINE ); -// writer.write( "Version: " ); -// writer.write( dep.getVersion() ); -// writer.write( NEWLINE ); -// writer.write( NEWLINE ); -// -// writer.write( "Reason: " ); -// writer.write( cause.getMessage() ); -// writer.write( NEWLINE ); -// -// result = true; -// } - // InvalidDependencyVersionException extends from InvalidProjectVersionException, so it comes first. -// else if ( e instanceof InvalidProjectVersionException ) -// { -// writer.write( NEWLINE ); -// writer.write( "You have an invalid version in your POM:" ); -// writer.write( NEWLINE ); -// writer.write( NEWLINE ); -// writer.write( "Location: " ); -// writer.write( ((InvalidProjectVersionException)e).getLocationInPom() ); -// writer.write( NEWLINE ); -// writer.write( NEWLINE ); -// writer.write( "Reason: " ); -// writer.write( cause.getMessage() ); -// writer.write( NEWLINE ); -// -// result = true; -// } - // now that we've sorted through all the sub-classes of ProjectBuildingException, - // let's look at causes of a basic PBE instance. -// else if ( ( cause instanceof ArtifactNotFoundException ) -// || ( cause instanceof ArtifactResolutionException ) ) -// { -// writer.write( NEWLINE ); -// writer.write( e.getMessage() ); -// writer.write( NEWLINE ); -// writer.write( NEWLINE ); -// writer.write( "Reason: " ); -// writer.write( cause.getMessage() ); -// writer.write( NEWLINE ); -// -// result = true; -// } - // handled by aspect binding to ProjectErrorReporter now. -// else if ( cause instanceof ProfileActivationException ) -// { -// writer.write( NEWLINE ); -// writer.write( "Profile activation failed. One or more named profile activators may be missing." ); -// writer.write( NEWLINE ); -// writer.write( NEWLINE ); -// writer.write( "Reason: " ); -// writer.write( cause.getMessage() ); -// writer.write( NEWLINE ); -// -// result = true; -// } -// else if ( cause instanceof IOException ) -// { -// writer.write( NEWLINE ); -// if ( e.getPomFile() == null ) -// { -// writer.write( "Error reading built-in super POM!" ); -// } -// else -// { -// writer.write( "Error reading POM." ); -// } -// writer.write( NEWLINE ); -// writer.write( NEWLINE ); -// writer.write( cause.getMessage() ); -// writer.write( NEWLINE ); -// } -// else if ( cause instanceof XmlPullParserException ) -// { -// writer.write( NEWLINE ); -// if ( e.getPomFile() == null ) -// { -// writer.write( "Error parsing built-in super POM!" ); -// } -// else -// { -// writer.write( "Error parsing POM." ); -// } -// writer.write( NEWLINE ); -// writer.write( NEWLINE ); -// writer.write( cause.getMessage() ); -// writer.write( NEWLINE ); -// writer.write( NEWLINE ); -// writer.write( "Line: " ); -// writer.write( "" + ( (XmlPullParserException) cause ).getLineNumber() ); -// writer.write( NEWLINE ); -// writer.write( "Column: " ); -// writer.write( "" + ( (XmlPullParserException) cause ).getColumnNumber() ); -// writer.write( NEWLINE ); -// -// result = true; -// } -// else if ( cause instanceof InvalidRepositoryException ) -// { -// writer.write( NEWLINE ); -// writer.write( "You have an invalid repository/pluginRepository declaration in your POM:" ); -// writer.write( NEWLINE ); -// writer.write( NEWLINE ); -// writer.write( "Repository-Id: " ); -// writer.write( ((InvalidRepositoryException)cause).getRepositoryId() ); -// writer.write( NEWLINE ); -// writer.write( NEWLINE ); -// writer.write( "Reason: " ); -// writer.write( cause.getMessage() ); -// writer.write( NEWLINE ); -// -// result = true; -// } - handleGenericException( e, showStackTraces, writer ); writer.write( NEWLINE ); @@ -772,216 +582,12 @@ public final class CLIReportingUtils return true; } + // NOTE: This method is an aspect target. private static boolean handleBuildFailureException( BuildFailureException e, boolean showStackTraces, StringWriter writer ) { - // ===================================================================== - // Cases covered (listed exceptions extend BuildFailureException): - // ===================================================================== - // - // AggregatedBuildFailureException(String, MojoBinding, MojoFailureException) - // - // InvalidTaskException(TaskValidationResult, LifecycleLoaderException) - // InvalidTaskException(TaskValidationResult, LifecycleSpecificationException) - // InvalidTaskException(TaskValidationResult, PluginLoaderException) - // - // NoGoalsSpecifiedException(String) - // - // ProjectBuildFailureException(String, MojoBinding, MojoFailureException) - // - // ProjectCycleException(List, String, CycleDetectedException) - - if ( e instanceof NoGoalsSpecifiedException ) - { - writer.write( NEWLINE ); - writer.write( "You have not specified any goals or lifecycle phases for Maven to execute." ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - writer.write( "Please, either specify a goal or lifecycle phase on the command line" ); - writer.write( NEWLINE ); - writer.write( "(you may want to try \'package\' to get started), or configure the " ); - writer.write( NEWLINE ); - writer.write( " element in the build section of your project POM." ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - writer.write( "NOTE: You can also chain multiple goals/phases together, as in the following example:" ); - writer.write( NEWLINE ); - writer.write( "mvn clean package" ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - writer.write( "For more information about which goals and phases are available, see the following:" ); - writer.write( NEWLINE ); - writer.write( "- Maven in 5 Minutes guide (http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html)" ); - writer.write( NEWLINE ); - writer.write( "- Maven User's documentation (http://maven.apache.org/users/)" ); - writer.write( NEWLINE ); - writer.write( "- Maven Plugins page (http://maven.apache.org/plugins/)" ); - writer.write( NEWLINE ); - writer.write( "- CodeHaus Mojos Project page (http://mojo.codehaus.org/plugins.html)" ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - - return true; - } - else if ( e instanceof AggregatedBuildFailureException ) - { - writer.write( NEWLINE ); - writer.write( "Mojo (aggregator): " ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - writer.write( " " ); - writer.write( MojoBindingUtils.toString( ( (AggregatedBuildFailureException) e ).getBinding() ) ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - writer.write( "FAILED while executing in directory:" ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - writer.write( " " ); - writer.write( ( (AggregatedBuildFailureException) e ).getExecutionRootDirectory() ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - writer.write( "Reason:" ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - - handleMojoFailureException( ( (AggregatedBuildFailureException) e ).getMojoFailureException(), - writer ); - - return true; - } - else if ( e instanceof ProjectBuildFailureException ) - { - writer.write( NEWLINE ); - writer.write( "Mojo: " ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - writer.write( " " ); - writer.write( MojoBindingUtils.toString( ( (ProjectBuildFailureException) e ).getBinding() ) ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - writer.write( "FAILED for project: " ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - writer.write( " " ); - writer.write( ( (ProjectBuildFailureException) e ).getProjectId() ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - writer.write( "Reason:" ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - - handleMojoFailureException( ( (ProjectBuildFailureException) e ).getMojoFailureException(), - writer ); - - return true; - } - else if ( e instanceof InvalidTaskException ) - { - String task = ( (InvalidTaskException) e ).getTask(); - Throwable cause = e.getCause(); - - writer.write( NEWLINE ); - writer.write( "Invalid mojo or lifecycle phase: " ); - writer.write( task ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - - if ( cause instanceof PluginLoaderException ) - { - writer.write( "Failed to load plugin: " ); - writer.write( ( (PluginLoaderException) cause ).getPluginKey() ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - } - else - { - writer.write( "Error message was: " ); - writer.write( e.getMessage() ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - - } - - if ( showStackTraces ) - { - writer.write( "Original error:" ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - handleGenericException( cause, showStackTraces, writer ); - } - else - { - writer.write( "Original error message was: " ); - writer.write( cause.getMessage() ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - } - - return true; - } - else if ( e instanceof ProjectCycleException ) - { - writer.write( NEWLINE ); - writer.write( "Maven has detected a cyclic relationship among a set of projects in the current build." ); - writer.write( NEWLINE ); - writer.write( "The projects involved are:" ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - - List projects = ( (ProjectCycleException) e ).getProjects(); - for ( Iterator it = projects.iterator(); it.hasNext(); ) - { - MavenProject project = (MavenProject) it.next(); - writer.write( "- " ); - writer.write( project.getId() ); - writer.write( " (path: " ); - writer.write( project.getFile().getPath() ); - writer.write( ")" ); - writer.write( NEWLINE ); - } - - writer.write( NEWLINE ); - writer.write( "NOTE: This cycle usually indicates two projects listing one another as dependencies, but" ); - writer.write( NEWLINE ); - writer.write( "may also indicate one project using another as a parent, plugin, or extension." ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - - if ( showStackTraces ) - { - writer.write( "Original error:" ); - writer.write( NEWLINE ); - writer.write( NEWLINE ); - - handleGenericException( ( (ProjectCycleException) e ).getCause(), - showStackTraces, - writer ); - - writer.write( NEWLINE ); - writer.write( NEWLINE ); - } - - return true; - } - - return false; - } - - private static boolean handleMojoFailureException( MojoFailureException error, - StringWriter writer ) - { - String message = error.getLongMessage(); - if ( message == null ) - { - message = error.getMessage(); - } - - writer.write( message ); - writer.write( NEWLINE ); - + handleGenericException( e, showStackTraces, writer ); return true; } diff --git a/maven-project/src/main/aspect/org/apache/maven/project/aspect/ProjectErrorReporterAspect.aj b/maven-project/src/main/aspect/org/apache/maven/project/aspect/AbstractProjectErrorReporterAspect.aj similarity index 90% rename from maven-project/src/main/aspect/org/apache/maven/project/aspect/ProjectErrorReporterAspect.aj rename to maven-project/src/main/aspect/org/apache/maven/project/aspect/AbstractProjectErrorReporterAspect.aj index bb6fcc5342..377682adf8 100644 --- a/maven-project/src/main/aspect/org/apache/maven/project/aspect/ProjectErrorReporterAspect.aj +++ b/maven-project/src/main/aspect/org/apache/maven/project/aspect/AbstractProjectErrorReporterAspect.aj @@ -3,7 +3,7 @@ package org.apache.maven.project.aspect; import org.apache.maven.project.error.DefaultProjectErrorReporter; import org.apache.maven.project.error.ProjectErrorReporter; -public abstract aspect ProjectErrorReporterAspect +public abstract aspect AbstractProjectErrorReporterAspect { private ProjectErrorReporter reporter; diff --git a/maven-project/src/main/aspect/org/apache/maven/project/aspect/PBEDerivativeReporterAspect.aj b/maven-project/src/main/aspect/org/apache/maven/project/aspect/PBEDerivativeReporterAspect.aj index a22a3025c8..a624126a88 100644 --- a/maven-project/src/main/aspect/org/apache/maven/project/aspect/PBEDerivativeReporterAspect.aj +++ b/maven-project/src/main/aspect/org/apache/maven/project/aspect/PBEDerivativeReporterAspect.aj @@ -20,7 +20,7 @@ import java.io.File; import java.util.Set; public privileged aspect PBEDerivativeReporterAspect - extends ProjectErrorReporterAspect + extends AbstractProjectErrorReporterAspect { // UnknownRepositoryLayoutException diff --git a/maven-project/src/main/aspect/org/apache/maven/project/aspect/ProfileErrorReporterAspect.aj b/maven-project/src/main/aspect/org/apache/maven/project/aspect/ProfileErrorReporterAspect.aj index aeca22cd70..287d8a033a 100644 --- a/maven-project/src/main/aspect/org/apache/maven/project/aspect/ProfileErrorReporterAspect.aj +++ b/maven-project/src/main/aspect/org/apache/maven/project/aspect/ProfileErrorReporterAspect.aj @@ -1,8 +1,6 @@ package org.apache.maven.project.aspect; import org.apache.maven.project.ProjectBuildingException; -import org.apache.maven.project.error.DefaultProjectErrorReporter; -import org.apache.maven.project.error.ProjectErrorReporter; import org.apache.maven.profiles.activation.ProfileActivator; import org.apache.maven.artifact.InvalidRepositoryException; import org.apache.maven.model.Model; @@ -31,7 +29,7 @@ import java.io.IOException; * coming from {@link DefaultProfileAdvisor}. */ public privileged aspect ProfileErrorReporterAspect - extends ProjectErrorReporterAspect + extends AbstractProjectErrorReporterAspect { protected pointcut componentLookupException( ComponentLookupException cause ): diff --git a/maven-project/src/main/aspect/org/apache/maven/project/aspect/ProjectArtifactErrorReporterAspect.aj b/maven-project/src/main/aspect/org/apache/maven/project/aspect/ProjectArtifactErrorReporterAspect.aj index be039a7716..9f7cfe5c40 100644 --- a/maven-project/src/main/aspect/org/apache/maven/project/aspect/ProjectArtifactErrorReporterAspect.aj +++ b/maven-project/src/main/aspect/org/apache/maven/project/aspect/ProjectArtifactErrorReporterAspect.aj @@ -10,7 +10,7 @@ import java.io.File; import java.util.List; public privileged aspect ProjectArtifactErrorReporterAspect - extends ProjectErrorReporterAspect + extends AbstractProjectErrorReporterAspect { private pointcut mlbldr_resolveParentFromRepositories( Parent parentRef, ArtifactRepository localRepo, diff --git a/maven-project/src/main/aspect/org/apache/maven/project/aspect/ProjectIOErrorReporterAspect.aj b/maven-project/src/main/aspect/org/apache/maven/project/aspect/ProjectIOErrorReporterAspect.aj index 225a2f0619..5eadedcc28 100644 --- a/maven-project/src/main/aspect/org/apache/maven/project/aspect/ProjectIOErrorReporterAspect.aj +++ b/maven-project/src/main/aspect/org/apache/maven/project/aspect/ProjectIOErrorReporterAspect.aj @@ -9,7 +9,7 @@ import java.io.File; import java.io.IOException; public privileged aspect ProjectIOErrorReporterAspect - extends ProjectErrorReporterAspect + extends AbstractProjectErrorReporterAspect { private pointcut pbldr_readProject( String projectId, File pomFile ):