View Javadoc
1   package org.apache.maven.project;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  import static org.hamcrest.Matchers.containsString;
22  import static org.junit.Assert.assertThat;
23  
24  import java.io.File;
25  import java.util.ArrayList;
26  import java.util.List;
27  
28  import org.apache.maven.artifact.Artifact;
29  import org.apache.maven.artifact.repository.ArtifactRepository;
30  import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
31  import org.codehaus.plexus.util.FileUtils;
32  
33  public class DefaultMavenProjectBuilderTest
34      extends AbstractMavenProjectTestCase
35  {
36  
37      private List<File> filesToDelete = new ArrayList<>();
38  
39      private File localRepoDir;
40  
41      @Override
42      public void setUp()
43          throws Exception
44      {
45          super.setUp();
46  
47          projectBuilder = lookup( ProjectBuilder.class );
48  
49          localRepoDir = new File( System.getProperty( "java.io.tmpdir" ), "local-repo." + System.currentTimeMillis() );
50          localRepoDir.mkdirs();
51  
52          filesToDelete.add( localRepoDir );
53      }
54  
55      @Override
56      public void tearDown()
57          throws Exception
58      {
59          super.tearDown();
60  
61          if ( !filesToDelete.isEmpty() )
62          {
63              for ( File file : filesToDelete )
64              {
65                  if ( file.exists() )
66                  {
67                      if ( file.isDirectory() )
68                      {
69                          FileUtils.deleteDirectory( file );
70                      }
71                      else
72                      {
73                          file.delete();
74                      }
75                  }
76              }
77          }
78      }
79  
80      protected MavenProject getProject( Artifact pom, boolean allowStub )
81          throws Exception
82      {
83          ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
84          configuration.setLocalRepository( getLocalRepository() );
85          initRepoSession( configuration );
86  
87          return projectBuilder.build( pom, allowStub, configuration ).getProject();
88      }
89  
90      /**
91       * Check that we can build ok from the middle pom of a (parent,child,grandchild) hierarchy
92       * @throws Exception
93       */
94      public void testBuildFromMiddlePom() throws Exception
95      {
96          File f1 = getTestFile( "src/test/resources/projects/grandchild-check/child/pom.xml");
97          File f2 = getTestFile( "src/test/resources/projects/grandchild-check/child/grandchild/pom.xml");
98  
99          getProject( f1 );
100 
101         // it's the building of the grandchild project, having already cached the child project
102         // (but not the parent project), which causes the problem.
103         getProject( f2 );
104     }
105 
106     public void testDuplicatePluginDefinitionsMerged()
107         throws Exception
108     {
109         File f1 = getTestFile( "src/test/resources/projects/duplicate-plugins-merged-pom.xml" );
110 
111         MavenProject project = getProject( f1 );
112         assertEquals( 2, project.getBuildPlugins().get( 0 ).getDependencies().size() );
113         assertEquals( 2, project.getBuildPlugins().get( 0 ).getExecutions().size() );
114         assertEquals( "first", project.getBuildPlugins().get( 0 ).getExecutions().get( 0 ).getId() );
115     }
116 
117     public void testFutureModelVersion()
118         throws Exception
119     {
120         File f1 = getTestFile( "src/test/resources/projects/future-model-version-pom.xml" );
121 
122         try
123         {
124             getProject( f1 );
125             fail( "Expected to fail for future versions" );
126         }
127         catch ( ProjectBuildingException e )
128         {
129             assertContains( "Building this project requires a newer version of Maven", e.getMessage() );
130         }
131     }
132 
133     public void testPastModelVersion()
134         throws Exception
135     {
136         // a Maven 1.x pom will not even
137         // update the resource if we stop supporting modelVersion 4.0.0
138         File f1 = getTestFile( "src/test/resources/projects/past-model-version-pom.xml" );
139 
140         try
141         {
142             getProject( f1 );
143             fail( "Expected to fail for past versions" );
144         }
145         catch ( ProjectBuildingException e )
146         {
147             assertContains( "Building this project requires an older version of Maven", e.getMessage() );
148         }
149     }
150 
151     public void testFutureSchemaModelVersion()
152         throws Exception
153     {
154         File f1 = getTestFile( "src/test/resources/projects/future-schema-model-version-pom.xml" );
155 
156         try
157         {
158             getProject( f1 );
159             fail( "Expected to fail for future versions" );
160         }
161         catch ( ProjectBuildingException e )
162         {
163             assertContains( "Building this project requires a newer version of Maven", e.getMessage() );
164         }
165     }
166 
167     private void assertContains( String expected, String actual )
168     {
169         if ( actual == null || !actual.contains( expected ) )
170         {
171             fail( "Expected: a string containing " + expected + "\nActual: " + ( actual == null
172                 ? "null"
173                 : "'" + actual + "'" ) );
174         }
175     }
176 
177     public void testBuildStubModelForMissingRemotePom()
178         throws Exception
179     {
180         Artifact pom = repositorySystem.createProjectArtifact( "org.apache.maven.its", "missing", "0.1" );
181         MavenProject project = getProject( pom, true );
182 
183         assertNotNull( project.getArtifactId() );
184 
185         assertNotNull( project.getRemoteArtifactRepositories() );
186         assertFalse( project.getRemoteArtifactRepositories().isEmpty() );
187 
188         assertNotNull( project.getPluginArtifactRepositories() );
189         assertFalse( project.getPluginArtifactRepositories().isEmpty() );
190 
191         assertNull( project.getParent() );
192         assertNull( project.getParentArtifact() );
193 
194         assertFalse( project.isExecutionRoot() );
195     }
196 
197     @Override
198     protected ArtifactRepository getLocalRepository()
199         throws Exception
200     {
201         ArtifactRepositoryLayout repoLayout = lookup( ArtifactRepositoryLayout.class, "default" );
202         ArtifactRepository r =
203             repositorySystem.createArtifactRepository( "local", "file://" + localRepoDir.getAbsolutePath(), repoLayout,
204                                                        null, null );
205         return r;
206     }
207 
208     public void xtestLoop()
209         throws Exception
210     {
211         while ( true )
212         {
213             File f1 = getTestFile( "src/test/resources/projects/duplicate-plugins-merged-pom.xml" );
214             getProject( f1 );
215         }
216     }
217 
218     public void testPartialResultUponBadDependencyDeclaration()
219         throws Exception
220     {
221         File pomFile = getTestFile( "src/test/resources/projects/bad-dependency.xml" );
222 
223         try
224         {
225             ProjectBuildingRequest request = newBuildingRequest();
226             request.setProcessPlugins( false );
227             request.setResolveDependencies( true );
228             projectBuilder.build( pomFile, request );
229             fail( "Project building did not fail despite invalid POM" );
230         }
231         catch ( ProjectBuildingException e )
232         {
233             List<ProjectBuildingResult> results = e.getResults();
234             assertNotNull( results );
235             assertEquals( 1, results.size() );
236             ProjectBuildingResult result = results.get( 0 );
237             assertNotNull( result );
238             assertNotNull( result.getProject() );
239             assertEquals( 1, result.getProblems().size() );
240             assertEquals( 1, result.getProject().getArtifacts().size() );
241             assertNotNull( result.getDependencyResolutionResult() );
242         }
243     }
244 
245     public void testImportScopePomResolvesFromPropertyBasedRepository()
246             throws Exception
247     {
248         File pomFile = getTestFile( "src/test/resources/projects/import-scope-pom-resolves-from-property-based-repository.xml" );
249         ProjectBuildingRequest request = newBuildingRequest();
250         request.setProcessPlugins( false );
251         request.setResolveDependencies( true );
252         projectBuilder.build( pomFile, request );
253     }
254 
255     /**
256      * Tests whether local version range parent references are build correctly.
257      *
258      * @throws Exception
259      */
260     public void testBuildValidParentVersionRangeLocally() throws Exception
261     {
262         File f1 = getTestFile( "src/test/resources/projects/parent-version-range-local-valid/child/pom.xml" );
263 
264         final MavenProject childProject = getProject( f1 );
265 
266         assertNotNull( childProject.getParentArtifact() );
267         assertEquals( childProject.getParentArtifact().getVersion(), "1" );
268         assertNotNull( childProject.getParent() );
269         assertEquals( childProject.getParent().getVersion(), "1" );
270         assertNotNull( childProject.getModel().getParent() );
271         assertEquals( childProject.getModel().getParent().getVersion(), "[1,10]" );
272     }
273 
274     /**
275      * Tests whether local version range parent references are build correctly.
276      *
277      * @throws Exception
278      */
279     public void testBuildParentVersionRangeLocallyWithoutChildVersion() throws Exception
280     {
281         File f1 =
282             getTestFile( "src/test/resources/projects/parent-version-range-local-child-without-version/child/pom.xml" );
283 
284         try
285         {
286             getProject( f1 );
287             fail( "Expected 'ProjectBuildingException' not thrown." );
288         }
289         catch ( final ProjectBuildingException e )
290         {
291             assertNotNull( e.getMessage() );
292             assertThat( e.getMessage(), containsString( "Version must be a constant" ) );
293         }
294     }
295 
296     /**
297      * Tests whether local version range parent references are build correctly.
298      *
299      * @throws Exception
300      */
301     public void testBuildParentVersionRangeLocallyWithChildVersionExpression() throws Exception
302     {
303         File f1 =
304             getTestFile(
305                 "src/test/resources/projects/parent-version-range-local-child-version-expression/child/pom.xml" );
306 
307         try
308         {
309             getProject( f1 );
310             fail( "Expected 'ProjectBuildingException' not thrown." );
311         }
312         catch ( final ProjectBuildingException e )
313         {
314             assertNotNull( e.getMessage() );
315             assertThat( e.getMessage(), containsString( "Version must be a constant" ) );
316         }
317     }
318 
319     /**
320      * Tests whether external version range parent references are build correctly.
321      *
322      * @throws Exception
323      */
324     public void testBuildParentVersionRangeExternally() throws Exception
325     {
326         File f1 = getTestFile( "src/test/resources/projects/parent-version-range-external-valid/pom.xml" );
327 
328         final MavenProject childProject = this.getProjectFromRemoteRepository( f1 );
329 
330         assertNotNull( childProject.getParentArtifact() );
331         assertEquals( childProject.getParentArtifact().getVersion(), "1" );
332         assertNotNull( childProject.getParent() );
333         assertEquals( childProject.getParent().getVersion(), "1" );
334         assertNotNull( childProject.getModel().getParent() );
335         assertEquals( childProject.getModel().getParent().getVersion(), "[1,1]" );
336     }
337 
338     /**
339      * Tests whether external version range parent references are build correctly.
340      *
341      * @throws Exception
342      */
343     public void testBuildParentVersionRangeExternallyWithoutChildVersion() throws Exception
344     {
345         File f1 =
346             getTestFile(
347                 "src/test/resources/projects/parent-version-range-external-child-without-version/pom.xml" );
348 
349         try
350         {
351             this.getProjectFromRemoteRepository( f1 );
352             fail( "Expected 'ProjectBuildingException' not thrown." );
353         }
354         catch ( final ProjectBuildingException e )
355         {
356             assertNotNull( e.getMessage() );
357             assertThat( e.getMessage(), containsString( "Version must be a constant" ) );
358         }
359     }
360 
361     /**
362      * Tests whether external version range parent references are build correctly.
363      *
364      * @throws Exception
365      */
366     public void testBuildParentVersionRangeExternallyWithChildVersionExpression() throws Exception
367     {
368         File f1 =
369             getTestFile(
370                 "src/test/resources/projects/parent-version-range-external-child-version-expression/pom.xml" );
371 
372         try
373         {
374             this.getProjectFromRemoteRepository( f1 );
375             fail( "Expected 'ProjectBuildingException' not thrown." );
376         }
377         catch ( final ProjectBuildingException e )
378         {
379             assertNotNull( e.getMessage() );
380             assertThat( e.getMessage(), containsString( "Version must be a constant" ) );
381         }
382     }
383 
384 }