diff --git a/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java b/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java index 7ae4027223..1f4acfadcb 100644 --- a/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java +++ b/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java @@ -28,8 +28,7 @@ import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.metadata.ResolutionGroup; import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.resolver.ArtifactNotFoundException; -import org.apache.maven.artifact.resolver.ArtifactResolutionException; +import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; @@ -65,9 +64,8 @@ import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; import java.net.MalformedURLException; import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -207,11 +205,19 @@ public class DefaultExtensionManager projectSessions.put( projectId, projectSession ); } - // if the extension is null, or if it's already been added to the current project-session, skip it. - if ( ( extensionArtifact != null ) && !projectSession.containsExtensionRealm( extensionArtifact ) ) + ArtifactFilter coreFilter = artifactFilterManager.getArtifactFilter(); + + // if the extension is null, + // if it's already been added to the current project-session, + // or if it's excluded by the core filter, + // + // skip it. + if ( ( extensionArtifact != null ) + && !projectSession.containsExtensionRealm( extensionArtifact ) + && coreFilter.include( extensionArtifact ) ) { ArtifactFilter filter = - new ProjectArtifactExceptionFilter( artifactFilterManager.getArtifactFilter(), projectArtifact ); + new ProjectArtifactExceptionFilter( coreFilter, projectArtifact ); ResolutionGroup resolutionGroup; @@ -229,25 +235,32 @@ public class DefaultExtensionManager // not declare plexus-utils but need it. MNG-2900 DefaultPluginManager.checkPlexusUtils( resolutionGroup, artifactFactory ); - Set dependencies = new HashSet( resolutionGroup.getArtifacts() ); + Set dependencies = new LinkedHashSet(); dependencies.add( extensionArtifact ); + dependencies.addAll( resolutionGroup.getArtifacts() ); + + ArtifactResolutionRequest dependencyReq = new ArtifactResolutionRequest().setArtifact( projectArtifact ) + .setArtifactDependencies( dependencies ) + .setFilter( filter ) + .setLocalRepository( localRepository ) + .setRemoteRepostories( remoteRepositories ) + .setMetadataSource( artifactMetadataSource ); // TODO: Make this work with managed dependencies, or an analogous management section in the POM. - ArtifactResolutionResult result; - try + ArtifactResolutionResult result = artifactResolver.resolve( dependencyReq ); + + if ( result.hasCircularDependencyExceptions() || result.hasErrorArtifactExceptions() + || result.hasMetadataResolutionExceptions() || result.hasVersionRangeViolations() ) { - result = artifactResolver.resolveTransitively( dependencies, projectArtifact, - Collections.EMPTY_MAP, localRepository, remoteRepositories, - artifactMetadataSource, filter ); + throw new ExtensionManagerException( "Failed to resolve extension: " + extensionArtifact, extensionArtifact, projectId, result ); } - catch ( ArtifactResolutionException e ) + + Set resultArtifacts = result.getArtifacts(); + + if ( !extensionArtifact.isResolved() || ( extensionArtifact.getFile() == null ) ) { - throw new ExtensionManagerException( "Unable to resolve one or more extension artifacts for: " + extensionArtifact.getId(), extensionArtifact, projectId, e ); - } - catch ( ArtifactNotFoundException e ) - { - throw new ExtensionManagerException( "One or more extension artifacts is missing for: " + extensionArtifact.getId(), extensionArtifact, projectId, e ); + throw new ExtensionManagerException( "Extension artifact was not resolved, or has no file associated with it.", extensionArtifact, projectId ); } ClassRealm extensionRealm; @@ -260,7 +273,7 @@ public class DefaultExtensionManager throw new ExtensionManagerException( "Unable to create extension ClassRealm for extension: " + extensionArtifact.getId() + " within session for project: " + projectId, extensionArtifact, projectId, e ); } - for ( Iterator i = result.getArtifacts().iterator(); i.hasNext(); ) + for ( Iterator i = resultArtifacts.iterator(); i.hasNext(); ) { Artifact a = (Artifact) i.next(); diff --git a/maven-core/src/main/java/org/apache/maven/extension/ExtensionManagerException.java b/maven-core/src/main/java/org/apache/maven/extension/ExtensionManagerException.java index f7d81904c8..2f1d2dae85 100644 --- a/maven-core/src/main/java/org/apache/maven/extension/ExtensionManagerException.java +++ b/maven-core/src/main/java/org/apache/maven/extension/ExtensionManagerException.java @@ -2,8 +2,7 @@ package org.apache.maven.extension; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException; -import org.apache.maven.artifact.resolver.ArtifactNotFoundException; -import org.apache.maven.artifact.resolver.ArtifactResolutionException; +import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.codehaus.plexus.PlexusContainerException; import org.codehaus.plexus.classworlds.realm.DuplicateRealmException; import org.codehaus.plexus.classworlds.realm.NoSuchRealmException; @@ -18,6 +17,7 @@ public class ExtensionManagerException private Artifact extensionArtifact; private final String projectId; + private ArtifactResolutionResult resolutionResult; public ExtensionManagerException( String message, Artifact extensionArtifact, @@ -39,26 +39,6 @@ public class ExtensionManagerException this.projectId = projectId; } - public ExtensionManagerException( String message, - Artifact extensionArtifact, - String projectId, - ArtifactResolutionException cause ) - { - super( message, cause ); - this.extensionArtifact = extensionArtifact; - this.projectId = projectId; - } - - public ExtensionManagerException( String message, - Artifact extensionArtifact, - String projectId, - ArtifactNotFoundException cause ) - { - super( message, cause ); - this.extensionArtifact = extensionArtifact; - this.projectId = projectId; - } - public ExtensionManagerException( String message, Artifact extensionArtifact, String projectId, @@ -115,6 +95,26 @@ public class ExtensionManagerException this.projectId = projectId; } + public ExtensionManagerException( String message, + Artifact extensionArtifact, + String projectId ) + { + super( message ); + this.extensionArtifact = extensionArtifact; + this.projectId = projectId; + } + + public ExtensionManagerException( String message, + Artifact extensionArtifact, + String projectId, + ArtifactResolutionResult result ) + { + super( message ); + this.extensionArtifact = extensionArtifact; + this.projectId = projectId; + resolutionResult = result; + } + public Artifact getExtensionArtifact() { return extensionArtifact; @@ -125,4 +125,9 @@ public class ExtensionManagerException return projectId; } + public ArtifactResolutionResult getArtifactResolutionResult() + { + return resolutionResult; + } + } diff --git a/maven-core/src/test/java/org/apache/maven/execution/MavenProjectSessionTest.java b/maven-core/src/test/java/org/apache/maven/execution/MavenProjectSessionTest.java new file mode 100644 index 0000000000..fd103f728c --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/execution/MavenProjectSessionTest.java @@ -0,0 +1,164 @@ +package org.apache.maven.execution; + +import org.apache.maven.artifact.Artifact; +import org.codehaus.plexus.PlexusContainerException; +import org.codehaus.plexus.PlexusTestCase; +import org.codehaus.plexus.classworlds.realm.DuplicateRealmException; +import org.easymock.MockControl; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public class MavenProjectSessionTest + extends PlexusTestCase +{ + + private Set mockControls = new HashSet(); + + private void replay() + { + for ( Iterator it = mockControls.iterator(); it.hasNext(); ) + { + MockControl ctl = (MockControl) it.next(); + ctl.replay(); + } + } + + private void verify() + { + for ( Iterator it = mockControls.iterator(); it.hasNext(); ) + { + MockControl ctl = (MockControl) it.next(); + ctl.verify(); + } + } + + public void testAddExtensionRealmThenContainsExtensionRealm_ReturnTrue() + throws PlexusContainerException + { + String projectId = "org.test:test-project1:1"; + + MavenProjectSession session = new MavenProjectSession( projectId, getContainer() ); + + ArtifactMock extMock = new ArtifactMock( "org.test.dep", "ext1", "2" ); + + replay(); + + try + { + session.createExtensionRealm( extMock.artifact ); + } + catch ( DuplicateRealmException e ) + { + e.printStackTrace(); + + fail( "ClassRealm for extension should not exist yet." ); + } + + assertTrue( "Should return true for containsExtensionRealm after extension is added.", session.containsExtensionRealm( extMock.artifact ) ); + + verify(); + } + + public void testConstructDisposeConstruct_OneExtension_NoDuplicateRealmException() + throws PlexusContainerException + { + String projectId = "org.test:test-project1:1"; + + MavenProjectSession session = new MavenProjectSession( projectId, getContainer() ); + + ArtifactMock extMock = new ArtifactMock( "org.test.dep", "ext1", "2" ); + + replay(); + + try + { + session.createExtensionRealm( extMock.artifact ); + } + catch ( DuplicateRealmException e ) + { + e.printStackTrace(); + + fail( "ClassRealm for extension should not exist yet." ); + } + + session.dispose(); + + session = new MavenProjectSession( projectId, getContainer() ); + + try + { + session.createExtensionRealm( extMock.artifact ); + } + catch ( DuplicateRealmException e ) + { + e.printStackTrace(); + + fail( "Should have disposed ClassRealm for extension." ); + } + + verify(); + } + + public void testAddSameExtensionTwice_DuplicateRealmException() + throws PlexusContainerException + { + String projectId = "org.test:test-project1:1"; + + MavenProjectSession session = new MavenProjectSession( projectId, getContainer() ); + + ArtifactMock extMock = new ArtifactMock( "org.test.dep", "ext1", "2" ); + + replay(); + + try + { + session.createExtensionRealm( extMock.artifact ); + } + catch ( DuplicateRealmException e ) + { + e.printStackTrace(); + + fail( "ClassRealm for extension should not exist yet." ); + } + + try + { + session.createExtensionRealm( extMock.artifact ); + fail( "Should not allow same extension to be added twice." ); + } + catch ( DuplicateRealmException e ) + { + } + + verify(); + } + + private class ArtifactMock + { + private MockControl ctl; + + private Artifact artifact; + + public ArtifactMock( String groupId, + String artifactId, + String version ) + { + ctl = MockControl.createControl( Artifact.class ); + artifact = (Artifact) ctl.getMock(); + + artifact.getGroupId(); + ctl.setReturnValue( groupId, MockControl.ZERO_OR_MORE ); + + artifact.getArtifactId(); + ctl.setReturnValue( artifactId, MockControl.ZERO_OR_MORE ); + + artifact.getVersion(); + ctl.setReturnValue( version, MockControl.ZERO_OR_MORE ); + + mockControls.add( ctl ); + } + } + +}