Plugins now load per-project, which means they can have different plugin-level dependencies and configurations per-project, even if they're running in the same reactor.

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@586515 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
John Dennis Casey 2007-10-19 16:02:31 +00:00
parent 2603a87757
commit 4aeb99b92b
7 changed files with 227 additions and 171 deletions

View File

@ -25,6 +25,7 @@ import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.PlexusContainerException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import java.util.Date;
@ -70,11 +71,20 @@ public class MavenSession
this.projectSessions = projectSessions;
}
// TODO: Figure out how/when we can shut down all the realms for extensions/plugins connected to each project session...
public MavenProjectSession getProjectSession( MavenProject project )
throws PlexusContainerException
{
String id = MavenProjectSession.createProjectId( project.getGroupId(), project.getArtifactId(), project.getVersion() );
return (MavenProjectSession) projectSessions.get( id );
MavenProjectSession projectSession = (MavenProjectSession) projectSessions.get( id );
if ( projectSession == null )
{
projectSession = new MavenProjectSession( id, container );
projectSessions.put( id, projectSession );
}
return projectSession;
}
public Map getPluginContext( PluginDescriptor pluginDescriptor,

View File

@ -57,6 +57,7 @@ import org.apache.maven.project.MavenProject;
import org.apache.maven.project.artifact.InvalidDependencyVersionException;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.PlexusContainerException;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.context.Context;
@ -146,7 +147,7 @@ public class DefaultLifecycleExecutor
session,
rootProject );
// TODO: probably don't want to do all this up front
// FIXME: This should be handled by the extension scanner.
try
{
Map handlers = findArtifactTypeHandlers( session );
@ -157,6 +158,7 @@ public class DefaultLifecycleExecutor
{
throw new LifecycleExecutionException(
"Plugin could not be not found while searching for artifact-type handlers.",
rootProject,
e );
}
@ -400,8 +402,20 @@ public class DefaultLifecycleExecutor
private ClassRealm setProjectLookupRealm( MavenSession session,
MavenProject rootProject )
throws LifecycleExecutionException
{
MavenProjectSession projectSession = session.getProjectSession( rootProject );
MavenProjectSession projectSession;
try
{
projectSession = session.getProjectSession( rootProject );
}
catch ( PlexusContainerException e )
{
throw new LifecycleExecutionException(
"Failed to create project-specific session for: "
+ rootProject.getId(),
rootProject, e );
}
if ( projectSession != null )
{
return container.setLookupRealm( projectSession.getProjectRealm() );
@ -443,7 +457,7 @@ public class DefaultLifecycleExecutor
{
throw new LifecycleExecutionException(
"Failed to construct build plan for: " + targetDescription
+ ". Reason: " + e.getMessage(),
+ ". Reason: " + e.getMessage(), project,
e );
}
@ -488,6 +502,7 @@ public class DefaultLifecycleExecutor
throw new LifecycleExecutionException(
"Failed to load plugin for: "
+ MojoBindingUtils.toString( mojoBinding ) + ". Reason: " + e.getMessage(),
project,
e );
}
}
@ -511,36 +526,42 @@ public class DefaultLifecycleExecutor
throw new LifecycleExecutionException(
"Internal error in the plugin manager executing goal '"
+ mojoDescriptor.getId() + "': " + e.getMessage(),
project,
e );
}
catch ( ArtifactNotFoundException e )
{
throw new LifecycleExecutionException(
e.getMessage(),
project,
e );
}
catch ( InvalidDependencyVersionException e )
{
throw new LifecycleExecutionException(
e.getMessage(),
project,
e );
}
catch ( ArtifactResolutionException e )
{
throw new LifecycleExecutionException(
e.getMessage(),
project,
e );
}
catch ( MojoExecutionException e )
{
throw new LifecycleExecutionException(
e.getMessage(),
project,
e );
}
catch ( PluginConfigurationException e )
{
throw new LifecycleExecutionException(
e.getMessage(),
project,
e );
}
}
@ -548,7 +569,7 @@ public class DefaultLifecycleExecutor
{
throw new LifecycleExecutionException(
"Failed to load plugin for: "
+ MojoBindingUtils.toString( mojoBinding ) + ". Reason: unknown" );
+ MojoBindingUtils.toString( mojoBinding ) + ". Reason: unknown", project );
}
}
catch ( LifecycleExecutionException e )
@ -789,6 +810,7 @@ public class DefaultLifecycleExecutor
throw new LifecycleExecutionException(
"Error looking up available components from plugin '"
+ plugin.getKey() + "': " + e.getMessage(),
project,
e );
}
@ -827,36 +849,42 @@ public class DefaultLifecycleExecutor
throw new LifecycleExecutionException(
"Internal error in the plugin manager getting plugin '"
+ plugin.getKey() + "': " + e.getMessage(),
project,
e );
}
catch ( PluginVersionResolutionException e )
{
throw new LifecycleExecutionException(
e.getMessage(),
project,
e );
}
catch ( InvalidPluginException e )
{
throw new LifecycleExecutionException(
e.getMessage(),
project,
e );
}
catch ( ArtifactNotFoundException e )
{
throw new LifecycleExecutionException(
e.getMessage(),
project,
e );
}
catch ( ArtifactResolutionException e )
{
throw new LifecycleExecutionException(
e.getMessage(),
project,
e );
}
catch ( PluginVersionNotFoundException e )
{
throw new LifecycleExecutionException(
e.getMessage(),
project,
e );
}
return pluginDescriptor;

View File

@ -11,7 +11,9 @@ 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.MavenProject;
import org.apache.maven.project.artifact.InvalidDependencyVersionException;
import org.codehaus.plexus.PlexusContainerException;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@ -39,87 +41,116 @@ import org.apache.maven.project.artifact.InvalidDependencyVersionException;
public class LifecycleExecutionException
extends Exception
{
public LifecycleExecutionException( String message )
private final MavenProject project;
public LifecycleExecutionException( String message, MavenProject project )
{
super( message );
this.project = project;
}
public LifecycleExecutionException( String message,
public LifecycleExecutionException( String message, MavenProject project,
PluginManagerException cause )
{
super( message, cause );
this.project = project;
}
public LifecycleExecutionException( String message,
public LifecycleExecutionException( String message, MavenProject project,
PluginNotFoundException cause )
{
super( message, cause );
this.project = project;
}
public LifecycleExecutionException( String message,
public LifecycleExecutionException( String message, MavenProject project,
PluginVersionResolutionException cause )
{
super( message, cause );
this.project = project;
}
public LifecycleExecutionException( String message,
public LifecycleExecutionException( String message, MavenProject project,
InvalidVersionSpecificationException cause )
{
super( message, cause );
this.project = project;
}
public LifecycleExecutionException( String message,
public LifecycleExecutionException( String message, MavenProject project,
InvalidPluginException cause )
{
super( message, cause );
this.project = project;
}
public LifecycleExecutionException( String message,
public LifecycleExecutionException( String message, MavenProject project,
ArtifactNotFoundException cause )
{
super( message, cause );
this.project = project;
}
public LifecycleExecutionException( String message,
public LifecycleExecutionException( String message, MavenProject project,
ArtifactResolutionException cause )
{
super( message, cause );
this.project = project;
}
public LifecycleExecutionException( String message,
PluginLoaderException cause )
MavenProject project, PluginLoaderException cause )
{
super( message, cause );
this.project = project;
}
public LifecycleExecutionException( String message,
LifecycleException cause )
MavenProject project, LifecycleException cause )
{
super( message, cause );
this.project = project;
}
public LifecycleExecutionException( String message,
public LifecycleExecutionException( String message, MavenProject project,
InvalidDependencyVersionException cause )
{
super( message, cause );
this.project = project;
}
public LifecycleExecutionException( String message,
public LifecycleExecutionException( String message, MavenProject project,
MojoExecutionException cause )
{
super( message, cause );
this.project = project;
}
public LifecycleExecutionException( String message,
public LifecycleExecutionException( String message, MavenProject project,
PluginConfigurationException cause )
{
super( message, cause );
this.project = project;
}
public LifecycleExecutionException( String message,
public LifecycleExecutionException( String message, MavenProject project,
PluginVersionNotFoundException cause )
{
super( message, cause );
this.project = project;
}
public LifecycleExecutionException( String message,
MavenProject project,
PlexusContainerException cause )
{
super( message, cause );
this.project = project;
}
public MavenProject getProject()
{
return project;
}
}

View File

@ -347,30 +347,31 @@ public class DefaultPluginManager
ClassRealm pluginRealm = null;
// if we have a project session, it must mean we have extensions...
// which in turn may alter the execution of a plugin.
MavenProjectSession projectSession = session.getProjectSession( project );
if ( projectSession != null )
MavenProjectSession projectSession;
try
{
try
{
pluginRealm = projectSession.getPluginRealm( projectPlugin );
}
catch ( NoSuchRealmException e )
{
getLogger().debug( "Plugin realm is missing for: " + projectPlugin.getKey() + ". New realm will be created." );
}
projectSession = session.getProjectSession( project );
}
else
catch ( PlexusContainerException e )
{
pluginRealm = container.getComponentRealm( key );
throw new PluginManagerException( plugin, "Failed to create project-specific session for project: " + project.getId()
+ ".", project, e );
}
try
{
pluginRealm = projectSession.getPluginRealm( projectPlugin );
}
catch ( NoSuchRealmException e )
{
getLogger().debug( "Plugin realm is missing for: " + projectPlugin.getKey() + ". New realm will be created." );
}
if ( ( pluginRealm != null ) && ( pluginRealm != container.getContainerRealm() ) )
{
getLogger().debug(
"Realm already exists for: " + key
+ ". Skipping addition..." );
+ " (realm id: " + pluginRealm.getId() + "). Skipping addition..." );
// we've already discovered this plugin, and configured it, so skip it this time.
return;
@ -384,70 +385,45 @@ public class DefaultPluginManager
try
{
if ( projectSession != null )
pluginRealm = projectSession.createPluginRealm( projectPlugin );
try
{
pluginRealm = projectSession.createPluginRealm( projectPlugin );
pluginRealm.addURL( pluginArtifact.getFile().toURI().toURL() );
}
catch ( MalformedURLException e )
{
throw new PluginContainerException( plugin, pluginRealm, "Error rendering plugin artifact: " + pluginArtifact.getId() + " as URL.", e );
}
for ( Iterator i = artifacts.iterator(); i.hasNext(); )
{
Artifact artifact = (Artifact) i.next();
try
{
pluginRealm.addURL( pluginArtifact.getFile().toURI().toURL() );
getLogger().debug( "Adding: " + artifact.getId() + " to plugin class-realm: " + key + " in project-session: " + project.getId() );
pluginRealm.addURL( artifact.getFile().toURI().toURL() );
}
catch ( MalformedURLException e )
{
throw new PluginContainerException( plugin, pluginRealm, "Error rendering plugin artifact: " + pluginArtifact.getId() + " as URL.", e );
}
for ( Iterator i = artifacts.iterator(); i.hasNext(); )
{
Artifact artifact = (Artifact) i.next();
try
{
getLogger().debug( "Adding: " + artifact.getId() + " to plugin class-realm: " + key + " in project-session: " + project.getId() );
pluginRealm.addURL( artifact.getFile().toURI().toURL() );
}
catch ( MalformedURLException e )
{
throw new PluginContainerException( plugin, pluginRealm, "Error rendering plugin artifact: " + artifact.getId() + " as URL.", e );
}
}
try
{
getLogger().debug( "Discovering components in realm: " + pluginRealm );
container.discoverComponents( pluginRealm, false );
}
catch ( PlexusConfigurationException e )
{
throw new PluginContainerException( plugin, pluginRealm, "Error re-scanning project realm for components.", e );
}
catch ( ComponentRepositoryException e )
{
throw new PluginContainerException( plugin, pluginRealm, "Error re-scanning project realm for components.", e );
throw new PluginContainerException( plugin, pluginRealm, "Error rendering plugin artifact: " + artifact.getId() + " as URL.", e );
}
}
else
try
{
List jars = new ArrayList();
for ( Iterator i = artifacts.iterator(); i.hasNext(); )
{
Artifact artifact = (Artifact) i.next();
jars.add( artifact.getFile() );
}
jars.add( pluginArtifact.getFile() );
// Now here we need the artifact coreArtifactFilter stuff
pluginRealm = container.createComponentRealm( key, jars );
getLogger().debug( "Discovering components in realm: " + pluginRealm );
container.discoverComponents( pluginRealm, false );
}
catch ( PlexusConfigurationException e )
{
throw new PluginContainerException( plugin, pluginRealm, "Error re-scanning project realm for components.", e );
}
catch ( ComponentRepositoryException e )
{
throw new PluginContainerException( plugin, pluginRealm, "Error re-scanning project realm for components.", e );
}
}
catch ( PlexusContainerException e )
{
throw new PluginContainerException( plugin, pluginRealm, "Failed to create realm for plugin '" + projectPlugin
+ ".", e );
}
catch ( DuplicateRealmException e )
{
@ -687,12 +663,15 @@ public class DefaultPluginManager
ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
ClassRealm pluginRealm = pluginDescriptor.getClassRealm();
ClassRealm oldRealm = null;
try
{
getLogger().debug( "Setting lookup realm and context classloader for plugin to: " + pluginRealm.getId() + " (instance is: " + pluginRealm + ")" );
Thread.currentThread().setContextClassLoader( pluginRealm );
ClassRealm oldRealm = container.setLookupRealm( pluginRealm );
oldRealm = container.setLookupRealm( pluginRealm );
plugin.execute();
@ -710,8 +689,6 @@ public class DefaultPluginManager
ctx.store( buildContextManager );
}
container.setLookupRealm( oldRealm );
dispatcher.dispatchEnd( event, goalExecId );
}
catch ( MojoExecutionException e )
@ -728,6 +705,10 @@ public class DefaultPluginManager
}
finally
{
if ( oldRealm != null )
{
container.setLookupRealm( oldRealm );
}
Thread.currentThread().setContextClassLoader( oldClassLoader );
}
@ -801,90 +782,62 @@ public class DefaultPluginManager
ClassRealm realm = null;
MavenProjectSession projectSession = session.getProjectSession( project );
if ( projectSession != null )
MavenProjectSession projectSession;
try
{
try
{
realm = projectSession.getPluginRealm( pluginDescriptor );
}
catch ( NoSuchRealmException e )
{
throw new PluginManagerException( mojoDescriptor, project, "Plugin realm: " + pluginDescriptor.getId() + " not found in project session for: " + project.getId(), e );
}
projectSession = session.getProjectSession( project );
}
else
catch ( PlexusContainerException e )
{
realm = mojoDescriptor.getPluginDescriptor().getClassRealm();
throw new PluginManagerException( mojoDescriptor, "Failed to create project-specific session for project: " + project.getId()
+ ".", project, e );
}
try
{
realm = projectSession.getPluginRealm( pluginDescriptor );
}
catch ( NoSuchRealmException e )
{
getLogger().debug( "Plugin realm: " + pluginDescriptor.getId() + " not found in project session for: " + project.getId() + ". Using project realm instead." );
realm = projectSession.getProjectRealm();
}
// We are forcing the use of the plugin realm for all lookups that might occur during
// the lifecycle that is part of the lookup. Here we are specifically trying to keep
// lookups that occur in contextualize calls in line with the right realm.
if ( realm != null )
ClassRealm oldRealm = container.setLookupRealm( realm );
getLogger().debug(
"Looking up mojo " + mojoDescriptor.getRoleHint() + " in realm "
+ realm.getId() + " - descRealmId="
+ mojoDescriptor.getRealmId() );
try
{
plugin = (Mojo) container.lookup( Mojo.ROLE, mojoDescriptor.getRoleHint(), realm );
}
catch ( ComponentLookupException e )
{
throw new PluginContainerException( mojoDescriptor, realm, "Unable to find the mojo '"
+ mojoDescriptor.getRoleHint() + "' in the plugin '"
+ pluginDescriptor.getPluginLookupKey() + "'", e );
}
finally
{
ClassRealm oldRealm = container.setLookupRealm( realm );
getLogger().debug(
"Looking up mojo " + mojoDescriptor.getRoleHint() + " in realm "
+ realm.getId() + " - descRealmId="
+ mojoDescriptor.getRealmId() );
try
{
plugin = (Mojo) container.lookup( Mojo.ROLE, mojoDescriptor.getRoleHint(), realm );
}
catch ( ComponentLookupException e )
{
throw new PluginContainerException( mojoDescriptor, realm, "Unable to find the mojo '"
+ mojoDescriptor.getRoleHint() + "' in the plugin '"
+ pluginDescriptor.getPluginLookupKey() + "'", e );
}
if ( plugin != null )
{
getLogger().debug(
"Looked up - " + plugin + " - "
+ plugin.getClass().getClassLoader() );
}
else
{
getLogger().warn( "No luck." );
}
container.setLookupRealm( oldRealm );
}
if ( plugin != null )
{
getLogger().debug(
"Looked up - " + plugin + " - "
+ plugin.getClass().getClassLoader() );
}
else
{
getLogger().info(
"Looking up mojo " + mojoDescriptor.getRoleHint()
+ " in default realm "
+ container.getLookupRealm() + " - descRealmId="
+ mojoDescriptor.getRealmId() );
try
{
plugin = (Mojo) container.lookup( Mojo.ROLE, mojoDescriptor.getRoleHint() );
}
catch ( ComponentLookupException e )
{
throw new PluginContainerException( mojoDescriptor, container.getContainerRealm(), "Unable to find the mojo '"
+ mojoDescriptor.getRoleHint() + "' in the plugin '"
+ pluginDescriptor.getPluginLookupKey() + "' (using core class realm)", e );
}
if ( plugin != null )
{
getLogger().info(
"Looked up - " + plugin + " - "
+ plugin.getClass().getClassLoader() );
}
else
{
getLogger().warn( "No luck." );
}
getLogger().warn( "No luck." );
}
if ( report && !( plugin instanceof MavenReport ) )

View File

@ -2,7 +2,6 @@ package org.apache.maven.plugin;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.codehaus.plexus.PlexusContainerException;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
@ -48,16 +47,6 @@ public class PluginContainerException
this.pluginRealm = pluginRealm;
}
public PluginContainerException( Plugin plugin,
ClassRealm pluginRealm,
String message,
PlexusContainerException e )
{
super( plugin, message, e );
this.pluginRealm = pluginRealm;
}
public PluginContainerException( Plugin plugin,
ClassRealm pluginRealm,
String message,

View File

@ -3,6 +3,7 @@ package org.apache.maven.plugin;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.PlexusContainerException;
import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
@ -54,10 +55,12 @@ public class PluginManagerException
protected PluginManagerException( Plugin plugin,
String message,
MavenProject project,
PlexusContainerException cause )
{
super( message, cause );
this.project = project;
pluginGroupId = plugin.getGroupId();
pluginArtifactId = plugin.getArtifactId();
pluginVersion = plugin.getVersion();
@ -152,6 +155,23 @@ public class PluginManagerException
goal = mojoDescriptor.getGoal();
}
public PluginManagerException( MojoDescriptor mojoDescriptor,
String message,
MavenProject project,
PlexusContainerException cause )
{
super( message, cause );
this.project = project;
PluginDescriptor pd = mojoDescriptor.getPluginDescriptor();
pluginGroupId = pd.getGroupId();
pluginArtifactId = pd.getArtifactId();
pluginVersion = pd.getVersion();
goal = mojoDescriptor.getGoal();
}
public String getPluginGroupId()
{
return pluginGroupId;

View File

@ -22,6 +22,9 @@ package org.apache.maven.profiles.activation;
import org.apache.maven.context.SystemBuildContext;
import org.apache.maven.model.Activation;
import org.apache.maven.model.Profile;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.codehaus.plexus.util.StringUtils;
import java.util.ArrayList;
@ -29,9 +32,11 @@ import java.util.List;
public class JdkPrefixProfileActivator
extends DetectedProfileActivator
implements LogEnabled
{
public static final String JDK_VERSION = "java.version";
private Logger logger;
public boolean isActive( Profile profile )
{
@ -41,6 +46,11 @@ public class JdkPrefixProfileActivator
SystemBuildContext systemContext = SystemBuildContext.getSystemBuildContext( getBuildContextManager(), true );
String javaVersion = systemContext.getSystemProperty( JDK_VERSION );
if ( javaVersion == null )
{
getLogger().warn( "Cannot locate java version property in SystemBuildContext: " + JDK_VERSION + ". NOT enabling profile: " + profile.getId() );
return false;
}
return isActive( javaVersion, jdk );
}
@ -142,4 +152,19 @@ public class JdkPrefixProfileActivator
}
return 0;
}
protected Logger getLogger()
{
if ( logger == null )
{
logger = new ConsoleLogger( Logger.LEVEL_INFO, "jdk-activator internal" );
}
return logger;
}
public void enableLogging( Logger logger )
{
this.logger = logger;
}
}