1 package org.apache.maven.shared.dependency.analyzer;
2
3 import java.io.File;
4 import java.util.Arrays;
5 import java.util.Collections;
6 import java.util.HashSet;
7 import java.util.List;
8 import java.util.Properties;
9 import java.util.Set;
10
11 import org.apache.commons.lang3.JavaVersion;
12 import org.apache.commons.lang3.SystemUtils;
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 import org.apache.maven.artifact.Artifact;
34 import org.apache.maven.artifact.DefaultArtifact;
35 import org.apache.maven.artifact.handler.ArtifactHandler;
36 import org.apache.maven.artifact.handler.DefaultArtifactHandler;
37 import org.apache.maven.artifact.versioning.VersionRange;
38 import org.apache.maven.project.MavenProject;
39 import org.apache.maven.shared.invoker.InvocationRequest;
40 import org.apache.maven.shared.invoker.InvocationResult;
41 import org.apache.maven.shared.test.plugin.BuildTool;
42 import org.apache.maven.shared.test.plugin.ProjectTool;
43 import org.apache.maven.shared.test.plugin.RepositoryTool;
44 import org.apache.maven.shared.test.plugin.TestToolsException;
45 import org.codehaus.plexus.PlexusTestCase;
46
47
48
49
50
51
52
53
54 public class DefaultProjectDependencyAnalyzerTest
55 extends PlexusTestCase
56 {
57
58
59 private BuildTool buildTool;
60
61 private ProjectTool projectTool;
62
63 private ProjectDependencyAnalyzer analyzer;
64
65 private static File localRepo;
66
67
68
69
70
71
72 protected void setUp()
73 throws Exception
74 {
75 super.setUp();
76
77 buildTool = (BuildTool) lookup( BuildTool.ROLE );
78
79 projectTool = (ProjectTool) lookup( ProjectTool.ROLE );
80
81 if ( localRepo == null )
82 {
83 RepositoryTool repositoryTool = (RepositoryTool) lookup( RepositoryTool.ROLE );
84 localRepo = repositoryTool.findLocalRepositoryDirectory();
85 System.out.println( "Local repository: " + localRepo );
86 }
87
88 analyzer = (ProjectDependencyAnalyzer) lookup( ProjectDependencyAnalyzer.ROLE );
89 }
90
91
92
93 public void testPom()
94 throws TestToolsException, ProjectDependencyAnalyzerException
95 {
96 compileProject( "pom/pom.xml" );
97
98 MavenProject project = getProject( "pom/pom.xml" );
99
100 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
101
102 ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis();
103
104 assertEquals( expectedAnalysis, actualAnalysis );
105 }
106
107 public void testJarWithNoDependencies()
108 throws TestToolsException, ProjectDependencyAnalyzerException
109 {
110 compileProject( "jarWithNoDependencies/pom.xml" );
111
112 MavenProject project = getProject( "jarWithNoDependencies/pom.xml" );
113
114 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
115
116 ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis();
117
118 assertEquals( expectedAnalysis, actualAnalysis );
119 }
120
121 public void testJava8methodRefs()
122 throws TestToolsException, ProjectDependencyAnalyzerException
123 {
124 if ( !SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
125 {
126 return;
127 }
128
129
130 compileProject( "java8methodRefs/pom.xml" );
131
132 MavenProject project = getProject( "java8methodRefs/pom.xml" );
133
134 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
135
136 Artifact project1 = createArtifact( "commons-io", "commons-io", "jar", "2.4", "compile" );
137 Artifact project2 = createArtifact( "commons-lang", "commons-lang", "jar", "2.6", "compile" );
138 Set<Artifact> usedDeclaredArtifacts = new HashSet<Artifact>( Arrays.asList( project1, project2 ) );
139
140 ProjectDependencyAnalysis expectedAnalysis =
141 new ProjectDependencyAnalysis( usedDeclaredArtifacts, new HashSet<Artifact>(), new HashSet<Artifact>(),
142 new HashSet<Artifact>() );
143
144 assertEquals( expectedAnalysis, actualAnalysis );
145 }
146
147 public void testInlinedStaticReference()
148 throws TestToolsException, ProjectDependencyAnalyzerException
149 {
150 if ( !SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
151 {
152 return;
153 }
154
155
156 compileProject( "inlinedStaticReference/pom.xml" );
157
158 MavenProject project = getProject( "inlinedStaticReference/pom.xml" );
159
160 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
161
162 Artifact project1 = createArtifact( "dom4j", "dom4j", "jar", "1.6.1", "compile" );
163 Set<Artifact> usedDeclaredArtifacts = Collections.singleton( project1 );
164
165 ProjectDependencyAnalysis expectedAnalysis =
166 new ProjectDependencyAnalysis( usedDeclaredArtifacts, new HashSet<Artifact>(), new HashSet<Artifact>(),
167 new HashSet<Artifact>() );
168
169 assertEquals( expectedAnalysis, actualAnalysis );
170 }
171
172 public void testJarWithCompileDependency()
173 throws TestToolsException, ProjectDependencyAnalyzerException
174 {
175 compileProject( "jarWithCompileDependency/pom.xml" );
176
177 MavenProject project2 = getProject( "jarWithCompileDependency/project2/pom.xml" );
178
179 if ( project2.getBuild().getOutputDirectory().contains( "${" ) )
180 {
181
182 throw new TestToolsException( "output directory was not interpolated: "
183 + project2.getBuild().getOutputDirectory() );
184 }
185
186 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project2 );
187
188 Artifact project1 = createArtifact( "org.apache.maven.shared.dependency-analyzer.tests",
189 "jarWithCompileDependency1", "jar", "1.0", "compile" );
190 Set<Artifact> usedDeclaredArtifacts = Collections.singleton( project1 );
191 ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null,
192 null );
193
194 assertEquals( expectedAnalysis, actualAnalysis );
195 }
196
197 public void testForceDeclaredDependenciesUsage()
198 throws TestToolsException, ProjectDependencyAnalyzerException
199 {
200 compileProject( "jarWithTestDependency/pom.xml" );
201
202 MavenProject project2 = getProject( "jarWithTestDependency/project2/pom.xml" );
203
204 ProjectDependencyAnalysis analysis = analyzer.analyze( project2 );
205
206 try
207 {
208 analysis.forceDeclaredDependenciesUsage( new String[] {
209 "org.apache.maven.shared.dependency-analyzer.tests:jarWithTestDependency1" } );
210 fail( "failure expected since junit dependency is declared-used" );
211 }
212 catch ( ProjectDependencyAnalyzerException pdae )
213 {
214 assertTrue( pdae.getMessage().contains( "Trying to force use of dependencies which are "
215 + "declared but already detected as used: "
216 + "[org.apache.maven.shared.dependency-analyzer.tests:jarWithTestDependency1]" ) );
217 }
218
219 try
220 {
221 analysis.forceDeclaredDependenciesUsage( new String[] { "undefined:undefined" } );
222 fail( "failure expected since undefined dependency is not declared" );
223 }
224 catch ( ProjectDependencyAnalyzerException pdae )
225 {
226 assertTrue( pdae.getMessage().contains( "Trying to force use of dependencies which are "
227 + "not declared: [undefined:undefined]" ) );
228 }
229 }
230
231 public void testJarWithTestDependency()
232 throws TestToolsException, ProjectDependencyAnalyzerException
233 {
234 compileProject( "jarWithTestDependency/pom.xml" );
235
236 MavenProject project2 = getProject( "jarWithTestDependency/project2/pom.xml" );
237
238 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project2 );
239
240 Artifact project1 = createArtifact( "org.apache.maven.shared.dependency-analyzer.tests",
241 "jarWithTestDependency1", "jar", "1.0", "test" );
242 Artifact junit = createArtifact( "junit", "junit", "jar", "3.8.1", "test" );
243
244 ProjectDependencyAnalysis expectedAnalysis;
245 if ( SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
246 {
247 Set<Artifact> usedDeclaredArtifacts = new HashSet<Artifact>( Arrays.asList( project1, junit ) );
248 expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null, null );
249 }
250 else
251 {
252
253 Set<Artifact> usedDeclaredArtifacts = Collections.singleton( project1 );
254 Set<Artifact> unusedDeclaredArtifacts = Collections.singleton( junit );
255 expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, unusedDeclaredArtifacts,
256 null );
257 }
258
259 assertEquals( expectedAnalysis, actualAnalysis );
260 }
261
262 public void testJarWithXmlTransitiveDependency()
263 throws TestToolsException, ProjectDependencyAnalyzerException
264 {
265 compileProject( "jarWithXmlTransitiveDependency/pom.xml" );
266
267 MavenProject project = getProject( "jarWithXmlTransitiveDependency/pom.xml" );
268
269 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
270
271 Artifact jdom = createArtifact( "dom4j", "dom4j", "jar", "1.6.1", "compile" );
272 Set<Artifact> usedDeclaredArtifacts = Collections.singleton( jdom );
273
274 ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null,
275 null );
276
277
278
279 }
280
281 public void testJarWithCompileScopedTestDependency()
282 throws TestToolsException, ProjectDependencyAnalyzerException
283 {
284 compileProject( "jarWithCompileScopedTestDependency/pom.xml" );
285
286 MavenProject project2 = getProject( "jarWithCompileScopedTestDependency/project2/pom.xml" );
287
288 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project2 );
289
290 Artifact artifact1 = createArtifact( "org.apache.maven.shared.dependency-analyzer.tests",
291 "jarWithCompileScopedTestDependency1", "jar", "1.0", "test" );
292 Artifact junit = createArtifact( "junit", "junit", "jar", "3.8.1", "compile" );
293
294 ProjectDependencyAnalysis expectedAnalysis;
295 if ( SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
296 {
297 Set<Artifact> usedDeclaredArtifacts = new HashSet<>( Arrays.asList( artifact1, junit ) );
298 Set<Artifact> nonTestScopedTestArtifacts = Collections.singleton( junit );
299 expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null,
300 nonTestScopedTestArtifacts );
301 }
302 else
303 {
304
305 Set<Artifact> usedDeclaredArtifacts = Collections.singleton( artifact1 );
306 Set<Artifact> unUsedDeclaredArtifacts = Collections.singleton( junit );
307 expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, unUsedDeclaredArtifacts,
308 null );
309 }
310
311 assertEquals( expectedAnalysis, actualAnalysis );
312 }
313
314 public void testJarWithRuntimeScopedTestDependency() throws TestToolsException, ProjectDependencyAnalyzerException
315 {
316
317 compileProject( "jarWithRuntimeScopedTestDependency/pom.xml" );
318
319 MavenProject project2 = getProject( "jarWithRuntimeScopedTestDependency/project2/pom.xml" );
320
321 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project2 );
322
323 Artifact artifact1 = createArtifact( "org.apache.maven.shared.dependency-analyzer.tests",
324 "jarWithRuntimeScopedTestDependency1", "jar", "1.0", "test" );
325 Artifact junit = createArtifact( "junit", "junit", "jar", "3.8.1", "runtime" );
326
327 ProjectDependencyAnalysis expectedAnalysis;
328 if ( SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
329 {
330 Set<Artifact> usedDeclaredArtifacts = new HashSet<>( Arrays.asList( artifact1, junit ) );
331 expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null,
332 null );
333 }
334 else
335 {
336
337 Set<Artifact> usedDeclaredArtifacts = Collections.singleton( artifact1 );
338 Set<Artifact> unUsedDeclaredArtifacts = Collections.singleton( junit );
339 expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, unUsedDeclaredArtifacts,
340 null );
341 }
342
343 assertEquals( expectedAnalysis, actualAnalysis );
344 }
345
346 public void testMultimoduleProject()
347 throws TestToolsException, ProjectDependencyAnalyzerException
348 {
349 compileProject( "multimoduleProject/pom.xml" );
350
351
352
353 MavenProject project = getProject( "multimoduleProject/module2/pom.xml" );
354 @SuppressWarnings( "unchecked" )
355 Set<Artifact> dependencyArtifacts = project.getArtifacts();
356 for ( Artifact artifact : dependencyArtifacts )
357 {
358 if ( artifact.getArtifactId().equals( "test-module1" ) )
359 {
360 File dir = getTestFile( "target/test-classes/", "multimoduleProject/module1/target/classes/" );
361 artifact.setFile( dir );
362 }
363 }
364
365 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
366
367 Artifact junit = createArtifact( "org.apache.maven.its.dependency", "test-module1", "jar", "1.0", "compile" );
368 Set<Artifact> usedDeclaredArtifacts = Collections.singleton( junit );
369
370 ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null,
371 null );
372
373 assertEquals( expectedAnalysis, actualAnalysis );
374 }
375
376 public void testTypeUseAnnotationDependency()
377 throws TestToolsException, ProjectDependencyAnalyzerException
378 {
379
380 if ( !SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
381 {
382 return;
383 }
384
385 Properties properties = new Properties();
386 properties.put( "maven.compiler.source", "1.8" );
387 properties.put( "maven.compiler.target", "1.8" );
388 compileProject( "typeUseAnnotationDependency/pom.xml", properties);
389
390 MavenProject usage = getProject( "typeUseAnnotationDependency/usage/pom.xml" );
391
392 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( usage );
393
394 Artifact annotation = createArtifact( "org.apache.maven.shared.dependency-analyzer.tests",
395 "typeUseAnnotationDependencyAnnotation", "jar", "1.0", "compile" );
396 Set<Artifact> usedDeclaredArtifacts = Collections.singleton( annotation );
397 ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis(usedDeclaredArtifacts, null, null,
398 null );
399
400 assertEquals( expectedAnalysis, actualAnalysis );
401 }
402
403 public void testTypeUseAnnotationDependencyOnLocalVariable()
404 throws TestToolsException, ProjectDependencyAnalyzerException
405 {
406
407 if ( !SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
408 {
409 return;
410 }
411
412 Properties properties = new Properties();
413 properties.put( "maven.compiler.source", "1.8" );
414 properties.put( "maven.compiler.target", "1.8" );
415 compileProject( "typeUseAnnotationDependency/pom.xml", properties);
416
417 MavenProject usage = getProject( "typeUseAnnotationDependency/usageLocalVar/pom.xml" );
418
419 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( usage );
420
421 Artifact annotation = createArtifact( "org.apache.maven.shared.dependency-analyzer.tests",
422 "typeUseAnnotationDependencyAnnotation", "jar", "1.0", "compile" );
423 Set<Artifact> usedDeclaredArtifacts = Collections.singleton( annotation );
424 ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis(usedDeclaredArtifacts, null, null,
425 null);
426
427 assertEquals( expectedAnalysis, actualAnalysis );
428 }
429
430
431
432 private void compileProject( String pomPath )
433 throws TestToolsException
434 {
435 compileProject( pomPath, new Properties() );
436 }
437
438 private void compileProject(String pomPath, Properties properties) throws TestToolsException {
439 File pom = getTestFile( "target/test-classes/", pomPath );
440 if ( SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_9 )
441 && !properties.containsKey( "maven.compiler.source" ) )
442 {
443 properties.put( "maven.compiler.source", "1.7" );
444 properties.put( "maven.compiler.target", "1.7" );
445 }
446
447 String httpsProtocols = System.getProperty( "https.protocols" );
448 if ( httpsProtocols != null )
449 {
450 properties.put( "https.protocols", httpsProtocols );
451 }
452
453 List<String> goals = Arrays.asList( "clean", "install" );
454 File log = new File( pom.getParentFile(), "build.log" );
455
456
457 InvocationRequest request = buildTool.createBasicInvocationRequest( pom, properties, goals, log );
458 request.setLocalRepositoryDirectory( localRepo );
459 InvocationResult result = buildTool.executeMaven( request );
460
461 assertNull( "Error compiling test project", result.getExecutionException() );
462 assertEquals( "Error compiling test project", 0, result.getExitCode() );
463 }
464
465 private MavenProject getProject( String pomPath )
466 throws TestToolsException
467 {
468 File pom = getTestFile( "target/test-classes/", pomPath );
469
470 return projectTool.readProjectWithDependencies( pom );
471 }
472
473 private Artifact createArtifact( String groupId, String artifactId, String type, String version, String scope )
474 {
475 VersionRange versionRange = VersionRange.createFromVersion( version );
476 ArtifactHandler handler = new DefaultArtifactHandler();
477
478 return new DefaultArtifact( groupId, artifactId, versionRange, scope, type, null, handler );
479 }
480 }