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.nio.file.Files;
23  import java.nio.file.Path;
24  import java.util.ArrayList;
25  import java.util.Collections;
26  import java.util.List;
27  import java.util.Properties;
28  import java.util.concurrent.atomic.AtomicInteger;
29  
30  import org.apache.commons.io.FileUtils;
31  import org.apache.maven.AbstractCoreMavenComponentTestCase;
32  import org.apache.maven.artifact.InvalidArtifactRTException;
33  import org.apache.maven.execution.MavenSession;
34  import org.apache.maven.model.Dependency;
35  import org.apache.maven.model.InputLocation;
36  import org.apache.maven.model.Plugin;
37  import org.apache.maven.model.building.FileModelSource;
38  import org.apache.maven.model.building.ModelBuildingRequest;
39  import org.apache.maven.model.building.ModelSource;
40  
41  import static org.hamcrest.Matchers.containsString;
42  import static org.hamcrest.Matchers.empty;
43  import static org.hamcrest.Matchers.hasKey;
44  import static org.hamcrest.Matchers.is;
45  import static org.junit.Assert.assertThat;
46  
47  public class ProjectBuilderTest extends AbstractCoreMavenComponentTestCase {
48      @Override
49      protected String getProjectsDirectory() {
50          return "src/test/projects/project-builder";
51      }
52  
53      public void testSystemScopeDependencyIsPresentInTheCompileClasspathElements() throws Exception {
54          File pom = getProject("it0063");
55  
56          Properties eps = new Properties();
57          eps.setProperty("jre.home", new File(pom.getParentFile(), "jdk/jre").getPath());
58  
59          MavenSession session = createMavenSession(pom, eps);
60          MavenProject project = session.getCurrentProject();
61  
62          // Here we will actually not have any artifacts because the ProjectDependenciesResolver is not involved here. So
63          // right now it's not valid to ask for artifacts unless plugins require the artifacts.
64  
65          project.getCompileClasspathElements();
66      }
67  
68      public void testBuildFromModelSource() throws Exception {
69          File pomFile = new File("src/test/resources/projects/modelsource/module01/pom.xml");
70          MavenSession mavenSession = createMavenSession(pomFile);
71          ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
72          configuration.setRepositorySession(mavenSession.getRepositorySession());
73          ModelSource modelSource = new FileModelSource(pomFile);
74          ProjectBuildingResult result =
75                  lookup(org.apache.maven.project.ProjectBuilder.class).build(modelSource, configuration);
76  
77          assertNotNull(result.getProject().getParentFile());
78      }
79  
80      public void testVersionlessManagedDependency() throws Exception {
81          File pomFile = new File("src/test/resources/projects/versionless-managed-dependency.xml");
82          MavenSession mavenSession = createMavenSession(null);
83          ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
84          configuration.setRepositorySession(mavenSession.getRepositorySession());
85  
86          try {
87              lookup(org.apache.maven.project.ProjectBuilder.class).build(pomFile, configuration);
88              fail();
89          } catch (ProjectBuildingException e) {
90              // this is expected
91          }
92      }
93  
94      public void testResolveDependencies() throws Exception {
95          File pomFile = new File("src/test/resources/projects/basic-resolveDependencies.xml");
96          MavenSession mavenSession = createMavenSession(null);
97          ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
98          configuration.setRepositorySession(mavenSession.getRepositorySession());
99          configuration.setResolveDependencies(true);
100 
101         // single project build entry point
102         ProjectBuildingResult result =
103                 lookup(org.apache.maven.project.ProjectBuilder.class).build(pomFile, configuration);
104         assertEquals(1, result.getProject().getArtifacts().size());
105         // multi projects build entry point
106         List<ProjectBuildingResult> results = lookup(org.apache.maven.project.ProjectBuilder.class)
107                 .build(Collections.singletonList(pomFile), false, configuration);
108         assertEquals(1, results.size());
109         MavenProject mavenProject = results.get(0).getProject();
110         assertEquals(1, mavenProject.getArtifacts().size());
111 
112         final MavenProject project = mavenProject;
113         final AtomicInteger artifactsResultInAnotherThread = new AtomicInteger();
114         Thread t = new Thread(new Runnable() {
115             @Override
116             public void run() {
117                 artifactsResultInAnotherThread.set(project.getArtifacts().size());
118             }
119         });
120         t.start();
121         t.join();
122         assertEquals(project.getArtifacts().size(), artifactsResultInAnotherThread.get());
123     }
124 
125     public void testDontResolveDependencies() throws Exception {
126         File pomFile = new File("src/test/resources/projects/basic-resolveDependencies.xml");
127         MavenSession mavenSession = createMavenSession(null);
128         ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
129         configuration.setRepositorySession(mavenSession.getRepositorySession());
130         configuration.setResolveDependencies(false);
131 
132         // single project build entry point
133         ProjectBuildingResult result =
134                 lookup(org.apache.maven.project.ProjectBuilder.class).build(pomFile, configuration);
135         assertEquals(0, result.getProject().getArtifacts().size());
136         // multi projects build entry point
137         List<ProjectBuildingResult> results = lookup(org.apache.maven.project.ProjectBuilder.class)
138                 .build(Collections.singletonList(pomFile), false, configuration);
139         assertEquals(1, results.size());
140         MavenProject mavenProject = results.get(0).getProject();
141         assertEquals(0, mavenProject.getArtifacts().size());
142     }
143 
144     public void testReadModifiedPoms() throws Exception {
145         String initialValue = System.setProperty(
146                 DefaultProjectBuilder.DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY, Boolean.toString(true));
147         // TODO a similar test should be created to test the dependency management (basically all usages
148         // of DefaultModelBuilder.getCache() are affected by MNG-6530
149 
150         Path tempDir = Files.createTempDirectory(null);
151         FileUtils.copyDirectory(new File("src/test/resources/projects/grandchild-check"), tempDir.toFile());
152         try {
153             MavenSession mavenSession = createMavenSession(null);
154             ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
155             configuration.setRepositorySession(mavenSession.getRepositorySession());
156             org.apache.maven.project.ProjectBuilder projectBuilder =
157                     lookup(org.apache.maven.project.ProjectBuilder.class);
158             File child = new File(tempDir.toFile(), "child/pom.xml");
159             // build project once
160             projectBuilder.build(child, configuration);
161             // modify parent
162             File parent = new File(tempDir.toFile(), "pom.xml");
163             String parentContent = FileUtils.readFileToString(parent, "UTF-8");
164             parentContent = parentContent.replace(
165                     "<packaging>pom</packaging>",
166                     "<packaging>pom</packaging><properties><addedProperty>addedValue</addedProperty></properties>");
167             FileUtils.write(parent, parentContent, "UTF-8");
168             // re-build pom with modified parent
169             ProjectBuildingResult result = projectBuilder.build(child, configuration);
170             assertThat(result.getProject().getProperties(), hasKey((Object) "addedProperty"));
171         } finally {
172             if (initialValue == null) {
173                 System.clearProperty(DefaultProjectBuilder.DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY);
174             } else {
175                 System.setProperty(DefaultProjectBuilder.DISABLE_GLOBAL_MODEL_CACHE_SYSTEM_PROPERTY, initialValue);
176             }
177             FileUtils.deleteDirectory(tempDir.toFile());
178         }
179     }
180 
181     public void testReadErroneousMavenProjectContainsReference() throws Exception {
182         File pomFile = new File("src/test/resources/projects/artifactMissingVersion.xml").getAbsoluteFile();
183         MavenSession mavenSession = createMavenSession(null);
184         ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
185         configuration.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
186         configuration.setRepositorySession(mavenSession.getRepositorySession());
187         org.apache.maven.project.ProjectBuilder projectBuilder = lookup(org.apache.maven.project.ProjectBuilder.class);
188 
189         // single project build entry point
190         try {
191             projectBuilder.build(pomFile, configuration);
192         } catch (ProjectBuildingException ex) {
193             assertEquals(1, ex.getResults().size());
194             MavenProject project = ex.getResults().get(0).getProject();
195             assertNotNull(project);
196             assertEquals("testArtifactMissingVersion", project.getArtifactId());
197             assertEquals(pomFile, project.getFile());
198         }
199 
200         // multi projects build entry point
201         try {
202             projectBuilder.build(Collections.singletonList(pomFile), false, configuration);
203         } catch (ProjectBuildingException ex) {
204             assertEquals(1, ex.getResults().size());
205             MavenProject project = ex.getResults().get(0).getProject();
206             assertNotNull(project);
207             assertEquals("testArtifactMissingVersion", project.getArtifactId());
208             assertEquals(pomFile, project.getFile());
209         }
210     }
211 
212     public void testReadInvalidPom() throws Exception {
213         File pomFile = new File("src/test/resources/projects/badPom.xml").getAbsoluteFile();
214         MavenSession mavenSession = createMavenSession(null);
215         ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
216         configuration.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
217         configuration.setRepositorySession(mavenSession.getRepositorySession());
218         org.apache.maven.project.ProjectBuilder projectBuilder = lookup(org.apache.maven.project.ProjectBuilder.class);
219 
220         // single project build entry point
221         try {
222             projectBuilder.build(pomFile, configuration);
223         } catch (InvalidArtifactRTException iarte) {
224             assertThat(iarte.getMessage(), containsString("The groupId cannot be empty."));
225         }
226 
227         // multi projects build entry point
228         try {
229             projectBuilder.build(Collections.singletonList(pomFile), false, configuration);
230         } catch (ProjectBuildingException ex) {
231             assertEquals(1, ex.getResults().size());
232             MavenProject project = ex.getResults().get(0).getProject();
233             assertNotNull(project);
234             assertNotSame(0, ex.getResults().get(0).getProblems().size());
235         }
236     }
237 
238     public void testReadParentAndChildWithRegularVersionSetParentFile() throws Exception {
239         List<File> toRead = new ArrayList<>(2);
240         File parentPom = getProject("MNG-6723");
241         toRead.add(parentPom);
242         toRead.add(new File(parentPom.getParentFile(), "child/pom.xml"));
243         MavenSession mavenSession = createMavenSession(null);
244         ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
245         configuration.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
246         configuration.setRepositorySession(mavenSession.getRepositorySession());
247         org.apache.maven.project.ProjectBuilder projectBuilder = lookup(org.apache.maven.project.ProjectBuilder.class);
248 
249         // read poms separately
250         boolean parentFileWasFoundOnChild = false;
251         for (File file : toRead) {
252             List<ProjectBuildingResult> results =
253                     projectBuilder.build(Collections.singletonList(file), false, configuration);
254             assertResultShowNoError(results);
255             MavenProject project = findChildProject(results);
256             if (project != null) {
257                 assertEquals(parentPom, project.getParentFile());
258                 parentFileWasFoundOnChild = true;
259             }
260         }
261         assertTrue(parentFileWasFoundOnChild);
262 
263         // read projects together
264         List<ProjectBuildingResult> results = projectBuilder.build(toRead, false, configuration);
265         assertResultShowNoError(results);
266         assertEquals(parentPom, findChildProject(results).getParentFile());
267         Collections.reverse(toRead);
268         results = projectBuilder.build(toRead, false, configuration);
269         assertResultShowNoError(results);
270         assertEquals(parentPom, findChildProject(results).getParentFile());
271     }
272 
273     private MavenProject findChildProject(List<ProjectBuildingResult> results) {
274         for (ProjectBuildingResult result : results) {
275             if (result.getPomFile().getParentFile().getName().equals("child")) {
276                 return result.getProject();
277             }
278         }
279         return null;
280     }
281 
282     private void assertResultShowNoError(List<ProjectBuildingResult> results) {
283         for (ProjectBuildingResult result : results) {
284             assertThat(result.getProblems(), is(empty()));
285             assertNotNull(result.getProject());
286         }
287     }
288 
289     public void testBuildProperties() throws Exception {
290         File file = new File(getProject("MNG-6716").getParentFile(), "project/pom.xml");
291         MavenSession mavenSession = createMavenSession(null);
292         ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
293         configuration.setRepositorySession(mavenSession.getRepositorySession());
294         configuration.setResolveDependencies(true);
295         List<ProjectBuildingResult> result = projectBuilder.build(Collections.singletonList(file), true, configuration);
296         MavenProject project = result.get(0).getProject();
297         // verify a few typical parameters are not duplicated
298         assertEquals(1, project.getTestCompileSourceRoots().size());
299         assertEquals(1, project.getCompileSourceRoots().size());
300         assertEquals(1, project.getMailingLists().size());
301         assertEquals(1, project.getResources().size());
302     }
303 
304     public void testPropertyInPluginManagementGroupId() throws Exception {
305         File pom = getProject("MNG-6983");
306 
307         MavenSession session = createMavenSession(pom);
308         MavenProject project = session.getCurrentProject();
309 
310         for (Plugin buildPlugin : project.getBuildPlugins()) {
311             assertNotNull("Missing version for build plugin " + buildPlugin.getKey(), buildPlugin.getVersion());
312         }
313     }
314 
315     public void testLocationTrackingResolution() throws Exception {
316         File pom = getProject("MNG-7648");
317 
318         MavenSession session = createMavenSession(pom);
319         MavenProject project = session.getCurrentProject();
320 
321         InputLocation dependencyLocation = null;
322         for (Dependency dependency : project.getDependencies()) {
323             if (dependency.getManagementKey().equals("org.apache.maven.its:a:jar")) {
324                 dependencyLocation = dependency.getLocation("version");
325             }
326         }
327         assertNotNull("missing dependency", dependencyLocation);
328         assertEquals(
329                 "org.apache.maven.its:bom:0.1", dependencyLocation.getSource().getModelId());
330 
331         InputLocation pluginLocation = null;
332         for (Plugin plugin : project.getBuildPlugins()) {
333             if (plugin.getKey().equals("org.apache.maven.plugins:maven-clean-plugin")) {
334                 pluginLocation = plugin.getLocation("version");
335             }
336         }
337         assertNotNull("missing build plugin", pluginLocation);
338         assertEquals(
339                 "org.apache.maven.its:parent:0.1", pluginLocation.getSource().getModelId());
340     }
341 }