You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by be...@apache.org on 2011/09/27 16:55:57 UTC

svn commit: r1176414 - in /maven/maven-3/trunk: maven-core/src/main/java/org/apache/maven/project/ maven-core/src/test/java/org/apache/maven/project/ maven-core/src/test/java/org/apache/maven/repository/ maven-core/src/test/resources/projects/ maven-mo...

Author: bentmann
Date: Tue Sep 27 14:55:56 2011
New Revision: 1176414

URL: http://svn.apache.org/viewvc?rev=1176414&view=rev
Log:
[MNG-5073] ProjectBuilder.build(File,ProjectBuildingRequest) returns null project if dependency version info is missing

Added:
    maven/maven-3/trunk/maven-core/src/test/resources/projects/bad-dependency.xml   (with props)
Modified:
    maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
    maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java
    maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java
    maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
    maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java
    maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
    maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblemCollector.java
    maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java

Modified: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java?rev=1176414&r1=1176413&r2=1176414&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java (original)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java Tue Sep 27 14:55:56 2011
@@ -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();
-                }
+                resolutionResult = resolveDependencies( project, config.session );
+            }
 
-                Set<Artifact> artifacts = new LinkedHashSet<Artifact>();
-                if ( resolutionResult.getDependencyGraph() != null )
-                {
-                    RepositoryUtils.toArtifacts( artifacts, resolutionResult.getDependencyGraph().getChildren(),
-                                                 Collections.singletonList( project.getArtifact().getId() ), null );
+            ProjectBuildingResult result = new DefaultProjectBuildingResult( project, modelProblems, resolutionResult );
 
-                    // 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 );
+            if ( error != null )
+            {
+                ProjectBuildingException e = new ProjectBuildingException( Arrays.asList( result ) );
+                e.initCause( error );
+                throw e;
             }
 
-            return new DefaultProjectBuildingResult( project, modelProblems, resolutionResult );
+            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() );

Modified: maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java?rev=1176414&r1=1176413&r2=1176414&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java (original)
+++ maven/maven-3/trunk/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java Tue Sep 27 14:55:56 2011
@@ -33,6 +33,7 @@ import org.apache.maven.model.InputSourc
 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 DefaultProjectDependenciesR
         {
             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 ) );
             }
         }

Modified: maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java?rev=1176414&r1=1176413&r2=1176414&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java (original)
+++ maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java Tue Sep 27 14:55:56 2011
@@ -124,12 +124,10 @@ public abstract class AbstractMavenProje
     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 AbstractMavenProje
                     message += problem + "\n";
                 }
                 System.out.println( message );
-                fail( message );
             }
 
             throw e;
@@ -156,11 +153,18 @@ public abstract class AbstractMavenProje
     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 )

Modified: maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java?rev=1176414&r1=1176413&r2=1176414&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java (original)
+++ maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java Tue Sep 27 14:55:56 2011
@@ -155,5 +155,32 @@ public class DefaultMavenProjectBuilderT
             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() );
+        }
+    }
+
 }

Modified: maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java?rev=1176414&r1=1176413&r2=1176414&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java (original)
+++ maven/maven-3/trunk/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java Tue Sep 27 14:55:56 2011
@@ -33,6 +33,7 @@ import org.sonatype.aether.spi.connector
 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 ) );
+                    }
                 }
             }
         }

Added: maven/maven-3/trunk/maven-core/src/test/resources/projects/bad-dependency.xml
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-core/src/test/resources/projects/bad-dependency.xml?rev=1176414&view=auto
==============================================================================
--- maven/maven-3/trunk/maven-core/src/test/resources/projects/bad-dependency.xml (added)
+++ maven/maven-3/trunk/maven-core/src/test/resources/projects/bad-dependency.xml Tue Sep 27 14:55:56 2011
@@ -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>

Propchange: maven/maven-3/trunk/maven-core/src/test/resources/projects/bad-dependency.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/maven-3/trunk/maven-core/src/test/resources/projects/bad-dependency.xml
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java?rev=1176414&r1=1176413&r2=1176414&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java (original)
+++ maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java Tue Sep 27 14:55:56 2011
@@ -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;
     }

Modified: maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblemCollector.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblemCollector.java?rev=1176414&r1=1176413&r2=1176414&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblemCollector.java (original)
+++ maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblemCollector.java Tue Sep 27 14:55:56 2011
@@ -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 );
+    }
+
 }

Modified: maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java
URL: http://svn.apache.org/viewvc/maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java?rev=1176414&r1=1176413&r2=1176414&view=diff
==============================================================================
--- maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java (original)
+++ maven/maven-3/trunk/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java Tue Sep 27 14:55:56 2011
@@ -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,29 +45,68 @@ 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 )
+        {
+            DefaultModelBuildingResult tmp = new DefaultModelBuildingResult();
+            if ( modelId == null )
+            {
+                modelId = "";
+            }
+            tmp.addModelId( modelId );
+            tmp.setRawModel( modelId, model );
+            tmp.setProblems( problems );
+            result = tmp;
+        }
+        else
         {
-            this.problems.addAll( problems );
+            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;
+    }
+
+    /**
      * Gets the model that could not be built properly.
      * 
      * @return The erroneous model or {@code null} if not available.
      */
     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 )