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