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 testJarWithNonTestScopedTestDependency()
282 throws TestToolsException, ProjectDependencyAnalyzerException
283 {
284 compileProject( "jarWithNonTestScopedTestDependency/pom.xml" );
285
286 MavenProject project2 = getProject( "jarWithNonTestScopedTestDependency/project2/pom.xml" );
287
288 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project2 );
289
290 Artifact artifact1 = createArtifact( "org.apache.maven.shared.dependency-analyzer.tests",
291 "jarWithNonTestScopedTestDependency1", "jar", "1.0", "test" );
292 Artifact junit = createArtifact( "junit", "junit", "jar", "3.8.1", "test" );
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 testMultimoduleProject()
315 throws TestToolsException, ProjectDependencyAnalyzerException
316 {
317 compileProject( "multimoduleProject/pom.xml" );
318
319
320
321 MavenProject project = getProject( "multimoduleProject/module2/pom.xml" );
322 @SuppressWarnings( "unchecked" )
323 Set<Artifact> dependencyArtifacts = project.getArtifacts();
324 for ( Artifact artifact : dependencyArtifacts )
325 {
326 if ( artifact.getArtifactId().equals( "test-module1" ) )
327 {
328 File dir = getTestFile( "target/test-classes/", "multimoduleProject/module1/target/classes/" );
329 artifact.setFile( dir );
330 }
331 }
332
333 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( project );
334
335 Artifact junit = createArtifact( "org.apache.maven.its.dependency", "test-module1", "jar", "1.0", "compile" );
336 Set<Artifact> usedDeclaredArtifacts = Collections.singleton( junit );
337
338 ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis( usedDeclaredArtifacts, null, null,
339 null );
340
341 assertEquals( expectedAnalysis, actualAnalysis );
342 }
343
344 public void testTypeUseAnnotationDependency()
345 throws TestToolsException, ProjectDependencyAnalyzerException
346 {
347
348 if ( !SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
349 {
350 return;
351 }
352
353 Properties properties = new Properties();
354 properties.put( "maven.compiler.source", "1.8" );
355 properties.put( "maven.compiler.target", "1.8" );
356 compileProject( "typeUseAnnotationDependency/pom.xml", properties);
357
358 MavenProject usage = getProject( "typeUseAnnotationDependency/usage/pom.xml" );
359
360 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( usage );
361
362 Artifact annotation = createArtifact( "org.apache.maven.shared.dependency-analyzer.tests",
363 "typeUseAnnotationDependencyAnnotation", "jar", "1.0", "compile" );
364 Set<Artifact> usedDeclaredArtifacts = Collections.singleton( annotation );
365 ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis(usedDeclaredArtifacts, null, null,
366 null );
367
368 assertEquals( expectedAnalysis, actualAnalysis );
369 }
370
371 public void testTypeUseAnnotationDependencyOnLocalVariable()
372 throws TestToolsException, ProjectDependencyAnalyzerException
373 {
374
375 if ( !SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
376 {
377 return;
378 }
379
380 Properties properties = new Properties();
381 properties.put( "maven.compiler.source", "1.8" );
382 properties.put( "maven.compiler.target", "1.8" );
383 compileProject( "typeUseAnnotationDependency/pom.xml", properties);
384
385 MavenProject usage = getProject( "typeUseAnnotationDependency/usageLocalVar/pom.xml" );
386
387 ProjectDependencyAnalysis actualAnalysis = analyzer.analyze( usage );
388
389 Artifact annotation = createArtifact( "org.apache.maven.shared.dependency-analyzer.tests",
390 "typeUseAnnotationDependencyAnnotation", "jar", "1.0", "compile" );
391 Set<Artifact> usedDeclaredArtifacts = Collections.singleton( annotation );
392 ProjectDependencyAnalysis expectedAnalysis = new ProjectDependencyAnalysis(usedDeclaredArtifacts, null, null,
393 null);
394
395 assertEquals( expectedAnalysis, actualAnalysis );
396 }
397
398
399
400 private void compileProject( String pomPath )
401 throws TestToolsException
402 {
403 compileProject( pomPath, new Properties() );
404 }
405
406 private void compileProject(String pomPath, Properties properties) throws TestToolsException {
407 File pom = getTestFile( "target/test-classes/", pomPath );
408 if ( SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_9 )
409 && !properties.containsKey( "maven.compiler.source" ) )
410 {
411 properties.put( "maven.compiler.source", "1.7" );
412 properties.put( "maven.compiler.target", "1.7" );
413 }
414
415 String httpsProtocols = System.getProperty( "https.protocols" );
416 if ( httpsProtocols != null )
417 {
418 properties.put( "https.protocols", httpsProtocols );
419 }
420
421 List<String> goals = Arrays.asList( "clean", "install" );
422 File log = new File( pom.getParentFile(), "build.log" );
423
424
425 InvocationRequest request = buildTool.createBasicInvocationRequest( pom, properties, goals, log );
426 request.setLocalRepositoryDirectory( localRepo );
427 InvocationResult result = buildTool.executeMaven( request );
428
429 assertNull( "Error compiling test project", result.getExecutionException() );
430 assertEquals( "Error compiling test project", 0, result.getExitCode() );
431 }
432
433 private MavenProject getProject( String pomPath )
434 throws TestToolsException
435 {
436 File pom = getTestFile( "target/test-classes/", pomPath );
437
438 return projectTool.readProjectWithDependencies( pom );
439 }
440
441 private Artifact createArtifact( String groupId, String artifactId, String type, String version, String scope )
442 {
443 VersionRange versionRange = VersionRange.createFromVersion( version );
444 ArtifactHandler handler = new DefaultArtifactHandler();
445
446 return new DefaultArtifact( groupId, artifactId, versionRange, scope, type, null, handler );
447 }
448 }