mirror of https://github.com/apache/maven.git
[MNG-5073] ProjectBuilder.build(File,ProjectBuildingRequest) returns null project if dependency version info is missing
git-svn-id: https://svn.apache.org/repos/asf/maven/maven-3/trunk@1176414 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
870a3b3e80
commit
c3bf134f57
|
@ -18,6 +18,7 @@ package org.apache.maven.project;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
|
@ -119,6 +120,7 @@ public class DefaultProjectBuilder
|
|||
MavenProject project = configuration.getProject();
|
||||
|
||||
List<ModelProblem> modelProblems = null;
|
||||
Throwable error = null;
|
||||
|
||||
if ( project == null )
|
||||
{
|
||||
|
@ -141,7 +143,13 @@ public class DefaultProjectBuilder
|
|||
}
|
||||
catch ( ModelBuildingException e )
|
||||
{
|
||||
throw new ProjectBuildingException( e.getModelId(), e.getMessage(), pomFile, e );
|
||||
result = e.getResult();
|
||||
if ( result == null || result.getEffectiveModel() == null )
|
||||
{
|
||||
throw new ProjectBuildingException( e.getModelId(), e.getMessage(), pomFile, e );
|
||||
}
|
||||
// validation error, continue project building and delay failing to help IDEs
|
||||
error = e;
|
||||
}
|
||||
|
||||
modelProblems = result.getProblems();
|
||||
|
@ -158,39 +166,19 @@ public class DefaultProjectBuilder
|
|||
|
||||
if ( configuration.isResolveDependencies() )
|
||||
{
|
||||
try
|
||||
{
|
||||
DefaultDependencyResolutionRequest resolution =
|
||||
new DefaultDependencyResolutionRequest( project, config.session );
|
||||
resolutionResult = dependencyResolver.resolve( resolution );
|
||||
}
|
||||
catch ( DependencyResolutionException e )
|
||||
{
|
||||
resolutionResult = e.getResult();
|
||||
}
|
||||
|
||||
Set<Artifact> artifacts = new LinkedHashSet<Artifact>();
|
||||
if ( resolutionResult.getDependencyGraph() != null )
|
||||
{
|
||||
RepositoryUtils.toArtifacts( artifacts, resolutionResult.getDependencyGraph().getChildren(),
|
||||
Collections.singletonList( project.getArtifact().getId() ), null );
|
||||
|
||||
// Maven 2.x quirk: an artifact always points at the local repo, regardless whether resolved or not
|
||||
LocalRepositoryManager lrm = config.session.getLocalRepositoryManager();
|
||||
for ( Artifact artifact : artifacts )
|
||||
{
|
||||
if ( !artifact.isResolved() )
|
||||
{
|
||||
String path = lrm.getPathForLocalArtifact( RepositoryUtils.toArtifact( artifact ) );
|
||||
artifact.setFile( new File( lrm.getRepository().getBasedir(), path ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
project.setResolvedArtifacts( artifacts );
|
||||
project.setArtifacts( artifacts );
|
||||
resolutionResult = resolveDependencies( project, config.session );
|
||||
}
|
||||
|
||||
return new DefaultProjectBuildingResult( project, modelProblems, resolutionResult );
|
||||
ProjectBuildingResult result = new DefaultProjectBuildingResult( project, modelProblems, resolutionResult );
|
||||
|
||||
if ( error != null )
|
||||
{
|
||||
ProjectBuildingException e = new ProjectBuildingException( Arrays.asList( result ) );
|
||||
e.initCause( error );
|
||||
throw e;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -198,6 +186,43 @@ public class DefaultProjectBuilder
|
|||
}
|
||||
}
|
||||
|
||||
private DependencyResolutionResult resolveDependencies( MavenProject project, RepositorySystemSession session )
|
||||
{
|
||||
DependencyResolutionResult resolutionResult = null;
|
||||
|
||||
try
|
||||
{
|
||||
DefaultDependencyResolutionRequest resolution = new DefaultDependencyResolutionRequest( project, session );
|
||||
resolutionResult = dependencyResolver.resolve( resolution );
|
||||
}
|
||||
catch ( DependencyResolutionException e )
|
||||
{
|
||||
resolutionResult = e.getResult();
|
||||
}
|
||||
|
||||
Set<Artifact> artifacts = new LinkedHashSet<Artifact>();
|
||||
if ( resolutionResult.getDependencyGraph() != null )
|
||||
{
|
||||
RepositoryUtils.toArtifacts( artifacts, resolutionResult.getDependencyGraph().getChildren(),
|
||||
Collections.singletonList( project.getArtifact().getId() ), null );
|
||||
|
||||
// Maven 2.x quirk: an artifact always points at the local repo, regardless whether resolved or not
|
||||
LocalRepositoryManager lrm = session.getLocalRepositoryManager();
|
||||
for ( Artifact artifact : artifacts )
|
||||
{
|
||||
if ( !artifact.isResolved() )
|
||||
{
|
||||
String path = lrm.getPathForLocalArtifact( RepositoryUtils.toArtifact( artifact ) );
|
||||
artifact.setFile( new File( lrm.getRepository().getBasedir(), path ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
project.setResolvedArtifacts( artifacts );
|
||||
project.setArtifacts( artifacts );
|
||||
|
||||
return resolutionResult;
|
||||
}
|
||||
|
||||
private List<String> getProfileIds( List<Profile> profiles )
|
||||
{
|
||||
List<String> ids = new ArrayList<String>( profiles.size() );
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.maven.model.InputSource;
|
|||
import org.codehaus.plexus.component.annotations.Component;
|
||||
import org.codehaus.plexus.component.annotations.Requirement;
|
||||
import org.codehaus.plexus.logging.Logger;
|
||||
import org.codehaus.plexus.util.StringUtils;
|
||||
import org.sonatype.aether.RepositorySystem;
|
||||
import org.sonatype.aether.RepositorySystemSession;
|
||||
import org.sonatype.aether.RequestTrace;
|
||||
|
@ -85,6 +86,12 @@ public class DefaultProjectDependenciesResolver
|
|||
{
|
||||
for ( Dependency dependency : project.getDependencies() )
|
||||
{
|
||||
if ( StringUtils.isEmpty( dependency.getGroupId() ) || StringUtils.isEmpty( dependency.getArtifactId() )
|
||||
|| StringUtils.isEmpty( dependency.getVersion() ) )
|
||||
{
|
||||
// guard against case where best-effort resolution for invalid models is requested
|
||||
continue;
|
||||
}
|
||||
collect.addDependency( RepositoryUtils.toDependency( dependency, stereotypes ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,12 +124,10 @@ public abstract class AbstractMavenProjectTestCase
|
|||
protected MavenProject getProjectWithDependencies( File pom )
|
||||
throws Exception
|
||||
{
|
||||
ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
|
||||
configuration.setLocalRepository( getLocalRepository() );
|
||||
ProjectBuildingRequest configuration = newBuildingRequest();
|
||||
configuration.setRemoteRepositories( Arrays.asList( new ArtifactRepository[] {} ) );
|
||||
configuration.setProcessPlugins( false );
|
||||
configuration.setResolveDependencies( true );
|
||||
initRepoSession( configuration );
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -146,7 +144,6 @@ public abstract class AbstractMavenProjectTestCase
|
|||
message += problem + "\n";
|
||||
}
|
||||
System.out.println( message );
|
||||
fail( message );
|
||||
}
|
||||
|
||||
throw e;
|
||||
|
@ -155,12 +152,19 @@ public abstract class AbstractMavenProjectTestCase
|
|||
|
||||
protected MavenProject getProject( File pom )
|
||||
throws Exception
|
||||
{
|
||||
ProjectBuildingRequest configuration = newBuildingRequest();
|
||||
|
||||
return projectBuilder.build( pom, configuration ).getProject();
|
||||
}
|
||||
|
||||
protected ProjectBuildingRequest newBuildingRequest()
|
||||
throws Exception
|
||||
{
|
||||
ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
|
||||
configuration.setLocalRepository( getLocalRepository() );
|
||||
initRepoSession( configuration );
|
||||
|
||||
return projectBuilder.build( pom, configuration ).getProject();
|
||||
return configuration;
|
||||
}
|
||||
|
||||
protected void initRepoSession( ProjectBuildingRequest request )
|
||||
|
|
|
@ -155,5 +155,32 @@ public class DefaultMavenProjectBuilderTest
|
|||
getProject( f1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testPartialResultUponBadDependencyDeclaration()
|
||||
throws Exception
|
||||
{
|
||||
File pomFile = getTestFile( "src/test/resources/projects/bad-dependency.xml" );
|
||||
|
||||
try
|
||||
{
|
||||
ProjectBuildingRequest request = newBuildingRequest();
|
||||
request.setProcessPlugins( false );
|
||||
request.setResolveDependencies( true );
|
||||
projectBuilder.build( pomFile, request );
|
||||
fail( "Project building did not fail despite invalid POM" );
|
||||
}
|
||||
catch ( ProjectBuildingException e )
|
||||
{
|
||||
List<ProjectBuildingResult> results = e.getResults();
|
||||
assertNotNull( results );
|
||||
assertEquals( 1, results.size() );
|
||||
ProjectBuildingResult result = results.get( 0 );
|
||||
assertNotNull( result );
|
||||
assertNotNull( result.getProject() );
|
||||
assertEquals( 1, result.getProblems().size() );
|
||||
assertEquals( 1, result.getProject().getArtifacts().size() );
|
||||
assertNotNull( result.getDependencyResolutionResult() );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.sonatype.aether.spi.connector.ArtifactUpload;
|
|||
import org.sonatype.aether.spi.connector.MetadataDownload;
|
||||
import org.sonatype.aether.spi.connector.MetadataUpload;
|
||||
import org.sonatype.aether.spi.connector.RepositoryConnector;
|
||||
import org.sonatype.aether.transfer.ArtifactNotFoundException;
|
||||
import org.sonatype.aether.transfer.ArtifactTransferException;
|
||||
|
||||
/**
|
||||
|
@ -77,7 +78,14 @@ public class TestRepositoryConnector
|
|||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
download.setException( new ArtifactTransferException( download.getArtifact(), repository, e ) );
|
||||
if ( !remoteFile.exists() )
|
||||
{
|
||||
download.setException( new ArtifactNotFoundException( download.getArtifact(), repository ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
download.setException( new ArtifactTransferException( download.getArtifact(), repository, e ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
<project>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>test</groupId>
|
||||
<artifactId>invalid</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>central</id>
|
||||
<url>file:src/test/remote-repo</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<!-- groupId deliberately missing -->
|
||||
<artifactId>b</artifactId>
|
||||
<version>0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.its</groupId>
|
||||
<artifactId>a</artifactId>
|
||||
<version>0.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -237,7 +237,7 @@ public class DefaultModelBuilder
|
|||
{
|
||||
DefaultModelBuildingResult result = new DefaultModelBuildingResult();
|
||||
|
||||
DefaultModelProblemCollector problems = new DefaultModelProblemCollector( null );
|
||||
DefaultModelProblemCollector problems = new DefaultModelProblemCollector( result );
|
||||
|
||||
DefaultProfileActivationContext profileActivationContext = getProfileActivationContext( request );
|
||||
|
||||
|
@ -245,6 +245,8 @@ public class DefaultModelBuilder
|
|||
List<Profile> activeExternalProfiles =
|
||||
profileSelector.getActiveProfiles( request.getProfiles(), profileActivationContext, problems );
|
||||
|
||||
result.setActiveExternalProfiles( activeExternalProfiles );
|
||||
|
||||
if ( !activeExternalProfiles.isEmpty() )
|
||||
{
|
||||
Properties profileProps = new Properties();
|
||||
|
@ -321,8 +323,7 @@ public class DefaultModelBuilder
|
|||
message += currentData.getId();
|
||||
|
||||
problems.add( ModelProblem.Severity.FATAL, message, null, null );
|
||||
throw new ModelBuildingException( problems.getRootModel(), problems.getRootModelId(),
|
||||
problems.getProblems() );
|
||||
throw problems.newModelBuildingException();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,12 +346,8 @@ public class DefaultModelBuilder
|
|||
resultData.setArtifactId( resultModel.getArtifactId() );
|
||||
resultData.setVersion( resultModel.getVersion() );
|
||||
|
||||
result.setProblems( problems.getProblems() );
|
||||
|
||||
result.setEffectiveModel( resultModel );
|
||||
|
||||
result.setActiveExternalProfiles( activeExternalProfiles );
|
||||
|
||||
for ( ModelData currentData : lineage )
|
||||
{
|
||||
String modelId = ( currentData != superData ) ? currentData.getId() : "";
|
||||
|
@ -380,7 +377,7 @@ public class DefaultModelBuilder
|
|||
{
|
||||
Model resultModel = result.getEffectiveModel();
|
||||
|
||||
DefaultModelProblemCollector problems = new DefaultModelProblemCollector( result.getProblems() );
|
||||
DefaultModelProblemCollector problems = new DefaultModelProblemCollector( result );
|
||||
problems.setSource( resultModel );
|
||||
problems.setRootModel( resultModel );
|
||||
|
||||
|
@ -419,7 +416,7 @@ public class DefaultModelBuilder
|
|||
|
||||
if ( problems.hasErrors() )
|
||||
{
|
||||
throw new ModelBuildingException( resultModel, problems.getRootModelId(), problems.getProblems() );
|
||||
throw problems.newModelBuildingException();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -499,8 +496,7 @@ public class DefaultModelBuilder
|
|||
{
|
||||
problems.add( Severity.FATAL, "Non-parseable POM " + modelSource.getLocation() + ": " + e.getMessage(),
|
||||
null, e );
|
||||
throw new ModelBuildingException( problems.getRootModel(), problems.getRootModelId(),
|
||||
problems.getProblems() );
|
||||
throw problems.newModelBuildingException();
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
|
@ -518,8 +514,7 @@ public class DefaultModelBuilder
|
|||
}
|
||||
}
|
||||
problems.add( Severity.FATAL, "Non-readable POM " + modelSource.getLocation() + ": " + msg, null, e );
|
||||
throw new ModelBuildingException( problems.getRootModel(), problems.getRootModelId(),
|
||||
problems.getProblems() );
|
||||
throw problems.newModelBuildingException();
|
||||
}
|
||||
|
||||
model.setPomFile( pomFile );
|
||||
|
@ -529,8 +524,7 @@ public class DefaultModelBuilder
|
|||
|
||||
if ( problems.hasFatalErrors() )
|
||||
{
|
||||
throw new ModelBuildingException( problems.getRootModel(), problems.getRootModelId(),
|
||||
problems.getProblems() );
|
||||
throw problems.newModelBuildingException();
|
||||
}
|
||||
|
||||
return model;
|
||||
|
@ -844,8 +838,7 @@ public class DefaultModelBuilder
|
|||
}
|
||||
|
||||
problems.add( Severity.FATAL, buffer.toString(), parent.getLocation( "" ), e );
|
||||
throw new ModelBuildingException( problems.getRootModel(), problems.getRootModelId(),
|
||||
problems.getProblems() );
|
||||
throw problems.newModelBuildingException();
|
||||
}
|
||||
|
||||
ModelBuildingRequest lenientRequest = request;
|
||||
|
@ -863,8 +856,7 @@ public class DefaultModelBuilder
|
|||
|
||||
Model parentModel = readModel( modelSource, null, lenientRequest, problems );
|
||||
|
||||
ModelData parentData =
|
||||
new ModelData( parentModel, parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
|
||||
ModelData parentData = new ModelData( parentModel, groupId, artifactId, version );
|
||||
|
||||
return parentData;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.apache.maven.model.building;
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -42,6 +41,8 @@ class DefaultModelProblemCollector
|
|||
implements ModelProblemCollector
|
||||
{
|
||||
|
||||
private final ModelBuildingResult result;
|
||||
|
||||
private List<ModelProblem> problems;
|
||||
|
||||
private String source;
|
||||
|
@ -52,9 +53,10 @@ class DefaultModelProblemCollector
|
|||
|
||||
private Set<ModelProblem.Severity> severities = EnumSet.noneOf( ModelProblem.Severity.class );
|
||||
|
||||
public DefaultModelProblemCollector( List<ModelProblem> problems )
|
||||
public DefaultModelProblemCollector( ModelBuildingResult result )
|
||||
{
|
||||
this.problems = ( problems != null ) ? problems : new ArrayList<ModelProblem>();
|
||||
this.result = result;
|
||||
this.problems = result.getProblems();
|
||||
|
||||
for ( ModelProblem problem : this.problems )
|
||||
{
|
||||
|
@ -176,4 +178,21 @@ class DefaultModelProblemCollector
|
|||
add( problem );
|
||||
}
|
||||
|
||||
public ModelBuildingException newModelBuildingException()
|
||||
{
|
||||
ModelBuildingResult result = this.result;
|
||||
if ( result.getModelIds().isEmpty() )
|
||||
{
|
||||
DefaultModelBuildingResult tmp = new DefaultModelBuildingResult();
|
||||
tmp.setEffectiveModel( result.getEffectiveModel() );
|
||||
tmp.setProblems( getProblems() );
|
||||
tmp.setActiveExternalProfiles( result.getActiveExternalProfiles() );
|
||||
String id = getRootModelId();
|
||||
tmp.addModelId( id );
|
||||
tmp.setRawModel( id, getRootModel() );
|
||||
result = tmp;
|
||||
}
|
||||
return new ModelBuildingException( result );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ package org.apache.maven.model.building;
|
|||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.maven.model.Model;
|
||||
|
@ -37,11 +37,7 @@ public class ModelBuildingException
|
|||
extends Exception
|
||||
{
|
||||
|
||||
private final Model model;
|
||||
|
||||
private final String modelId;
|
||||
|
||||
private final List<ModelProblem> problems;
|
||||
private final ModelBuildingResult result;
|
||||
|
||||
/**
|
||||
* Creates a new exception with the specified problems.
|
||||
|
@ -49,19 +45,50 @@ public class ModelBuildingException
|
|||
* @param model The model that could not be built, may be {@code null}.
|
||||
* @param modelId The identifier of the model that could not be built, may be {@code null}.
|
||||
* @param problems The problems that causes this exception, may be {@code null}.
|
||||
* @deprecated Use {@link #ModelBuildingException(ModelBuildingResult)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public ModelBuildingException( Model model, String modelId, List<ModelProblem> problems )
|
||||
{
|
||||
super( toMessage( modelId, problems ) );
|
||||
|
||||
this.model = model;
|
||||
this.modelId = ( modelId != null ) ? modelId : "";
|
||||
|
||||
this.problems = new ArrayList<ModelProblem>();
|
||||
if ( problems != null )
|
||||
if ( model != null )
|
||||
{
|
||||
this.problems.addAll( problems );
|
||||
DefaultModelBuildingResult tmp = new DefaultModelBuildingResult();
|
||||
if ( modelId == null )
|
||||
{
|
||||
modelId = "";
|
||||
}
|
||||
tmp.addModelId( modelId );
|
||||
tmp.setRawModel( modelId, model );
|
||||
tmp.setProblems( problems );
|
||||
result = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new exception from the specified interim result and its associated problems.
|
||||
*
|
||||
* @param result The interim result, may be {@code null}.
|
||||
*/
|
||||
public ModelBuildingException( ModelBuildingResult result )
|
||||
{
|
||||
super( toMessage( result ) );
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the interim result of the model building up to the point where it failed.
|
||||
*
|
||||
* @return The interim model building result or {@code null} if not available.
|
||||
*/
|
||||
public ModelBuildingResult getResult()
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,7 +98,15 @@ public class ModelBuildingException
|
|||
*/
|
||||
public Model getModel()
|
||||
{
|
||||
return model;
|
||||
if ( result == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if ( result.getEffectiveModel() != null )
|
||||
{
|
||||
return result.getEffectiveModel();
|
||||
}
|
||||
return result.getRawModel();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,7 +118,11 @@ public class ModelBuildingException
|
|||
*/
|
||||
public String getModelId()
|
||||
{
|
||||
return modelId;
|
||||
if ( result == null || result.getModelIds().isEmpty() )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return result.getModelIds().get( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -93,7 +132,20 @@ public class ModelBuildingException
|
|||
*/
|
||||
public List<ModelProblem> getProblems()
|
||||
{
|
||||
return problems;
|
||||
if ( result == null )
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return result.getProblems();
|
||||
}
|
||||
|
||||
private static String toMessage( ModelBuildingResult result )
|
||||
{
|
||||
if ( result != null && !result.getModelIds().isEmpty() )
|
||||
{
|
||||
return toMessage( result.getModelIds().get( 0 ), result.getProblems() );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String toMessage( String modelId, List<ModelProblem> problems )
|
||||
|
|
Loading…
Reference in New Issue