assembly:assembly forks a lifecycle and cannot be used in a reactor
environment. Need a new mojo suitable for this environment,
-------------------------------------------------------------------------------------------------------------------------------
Key: MNG-1462
URL: http://jira.codehaus.org/browse/MNG-1462
Project: Maven 2
Type: Improvement
Components: maven-assembly-plugin
Versions: 2.0
Reporter: Jerome Lacoste
Priority: Critical
Basically I use the assembly plugin in a module under the reactor project.
I attach the assembly plugin to the verify phase (because of MNG-1311), but
somehow when my module is being processed, the plugin is executed for the
package phase and it
forks the full project lifecycle, because it is an aggregator.
This triggers the rebuild all my reactor projects.
This happens twice (I have 2 modules which use the assembly plugin),
making my build 3 times too long.
Now investigating the issue.
The stack trace looks like:
private void executeGoalAndHandleFailures( String task, MavenSession session,
MavenProject project,
EventDispatcher dispatcher, String
event, ReactorManager rm,
long buildStartTime, String target )
private void executeGoal( String task, MavenSession session, MavenProject
project )
private void executeGoalWithLifecycle( String task, MavenSession session, Map
lifecycleMappings,
MavenProject project, Lifecycle
lifecycle )
private void executeGoals( List goals, MavenSession session, MavenProject
project )
throws LifecycleExecutionException, BuildFailureException,
PluginNotFoundException
private void forkLifecycle( MojoDescriptor mojoDescriptor, MavenSession
session, MavenProject project )
throws LifecycleExecutionException, BuildFailureException,
PluginNotFoundException
which creates the redundancy here:
private void forkLifecycle( MojoDescriptor mojoDescriptor, MavenSession
session, MavenProject project )
throws LifecycleExecutionException, BuildFailureException,
PluginNotFoundException
{
PluginDescriptor pluginDescriptor =
mojoDescriptor.getPluginDescriptor();
getLogger().info( "Preparing " + pluginDescriptor.getGoalPrefix() + ":"
+ mojoDescriptor.getGoal() );
if ( mojoDescriptor.isAggregator() )
{
for ( Iterator i = session.getSortedProjects().iterator();
i.hasNext(); )
{
MavenProject reactorProject = (MavenProject) i.next();
line();
getLogger().info( "Building " + reactorProject.getName() );
line();
forkProjectLifecycle( mojoDescriptor, session, reactorProject );
}
}
else
{
forkProjectLifecycle( mojoDescriptor, session, project );
}
}
The redundancy appears because the assembly plugin is an aggregator so if
forked it will fork all reactor projects.
It is forked in my case because the execute phase is not null.
In DefaultLifeCycleExecutor:
private void executeGoals( List goals, MavenSession session, MavenProject
project )
throws LifecycleExecutionException, BuildFailureException,
PluginNotFoundException
{
for ( Iterator i = goals.iterator(); i.hasNext(); )
{
MojoExecution mojoExecution = (MojoExecution) i.next();
MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
if ( mojoDescriptor.getExecutePhase() != null ||
mojoDescriptor.getExecuteGoal() != null )
{
forkLifecycle( mojoDescriptor, session, project );
}
and getExecutePhase() is "package"
Now before executing this:
Map lifecycleMappings = constructLifecycleMappings( session,
task, project, lifecycle );
executeGoalWithLifecycle( task, session, lifecycleMappings,
project, lifecycle );
my lifecycleMappings contains 3 entries each with a list of single
MojoExecution instances
install -> ME21
verify -> MJ17
test -> MJ20
Then when this mappings are processed as a goal chain:
List goals = processGoalChain( task, lifecycleMappings, lifecycle );
The goals have been sorted so that:
(MJ20, MJ17, MJ21) which looks OK to me.
which were constructed by:
private Map constructLifecycleMappings( MavenSession session, String
selectedPhase, MavenProject project,
Lifecycle lifecycle )
throws LifecycleExecutionException, BuildFailureException,
PluginNotFoundException
{
// first, bind those associated with the packaging
Map lifecycleMappings = bindLifecycleForPackaging( session,
selectedPhase, project, lifecycle );
// next, loop over plugins and for any that have a phase, bind it
for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext(); )
{
Plugin plugin = (Plugin) i.next();
bindPluginToLifecycle( plugin, session, lifecycleMappings, project
);
}
return lifecycleMappings;
}
Links to a somewhat related issue: http://jira.codehaus.org/browse/MNG-1311
Now a little chat with jdcasey conclude that a new Mojo needs to be created:
(18:02:35) jdcasey: CoffeeBre: it doesn't seem to have anything to do with it
being an aggregator...it's all based on that @execute phase="package" annotation
(18:02:48) jdcasey: that prompts the lifecycle executor to fork the lifecycle,
and re-run package
(18:02:50) jdcasey: hmm
(18:03:49) jdcasey: looks like this mojo isn't designed to be integrated into
the lifecycle
(18:04:13) jdcasey: it looks like you'd have to write another mojo front-end
for the assembly process, which doesn't specify @execute phase="package" in it.
(18:04:49) jdcasey: the mojo could be a thin wrapper around the real guts,
which would be in a separate class
(18:05:15) jdcasey: I think that would be the simplest way around.
(18:05:43) ***jdcasey thinks the @execute annotation is poorly named...
(18:05:46) CoffeeBre: what about removing the @execute phase instaed?
(18:06:02) jdcasey: well, then you lose the ability to call 'mvn
assembly:assembly'
(18:06:10) jdcasey: because it requires the package phase.
(18:07:04) jdcasey: something like assembly:attached would be good,
IMO...that's what you want to do, right? attach them to the main project
artifact so they're installed/deployed too?
(18:07:27) jdcasey: that new mojo could reference the same code, which would be
factored into a general case api in that plugin
(18:07:34) CoffeeBre: and with regard to the aggregator, I mentionned it
because of line 701 in DefaultLifeCycleExecutor
(18:08:02) jdcasey: yeah, but if you look, that just determines *how* the
lifecycle is forked, not *whether*
(18:08:32) CoffeeBre: you mean it shouldn't be forked at all? (I am trying to
follow)
(18:10:42) jdcasey: CoffeeBre: you need a new mojo that integrates with the
existing lifecycle, but has to bind on or after the package phase...rather than
forking
(18:11:57) CoffeeBre: jdcasey: see also MNG-1310 and MNG-1274. related to my
use of the assembly plugin
(18:16:53) CoffeeBre: jdcasey: trying to summarize. If I follow you, the issue
is because the assembly:assembly mojo is forking and we don't want that. So I
create a simple Mojo wrapper within the assembly plugin with 2 differences. Map
to assembly:attached, and do not specify a @execute. Could that be the solution
for MNG-1311 as well?
(18:17:45) jdcasey: CoffeeBre: that won't solve MNG-1311, because we need to
eliminate the infinite loop (thought I worked on that once already)
(18:18:16) jdcasey: CoffeeBre: you may need to factor some logic out of the
existing AssemblyMojo into a common class, or extend it (not sure whether the
annotations will show through when extending)
(18:18:41) jdcasey: if you factor into common API, and reference from both the
AssemblyMojo and the new AttachedAssemblyMojo (or whatever) it'll definitely
work
(18:18:56) jdcasey: but the new mojo should *not* specify the execute stuff
(18:19:46) jdcasey: CoffeeBre, jeremyw: I've gotta run out for a bit, but I'll
be back in like an hour or so
(18:19:58) CoffeeBre: jdcasey: I wondered if the infinite loop was not created
by the fact that the plugin was aggregating all the projects
(18:20:35) jdcasey: CoffeeBre: um, possibly...but I think aggregation is
appropriate here...not sure, I'd have to investigate further.
(18:20:49) CoffeeBre: jdcasey: ok. Have to run out as well. Will create an
issue and add info there.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.codehaus.org/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]