50
50
import org .apache .maven .plugins .annotations .Parameter ;
51
51
import org .apache .maven .plugins .annotations .ResolutionScope ;
52
52
import org .codehaus .plexus .util .xml .Xpp3Dom ;
53
+ import org .eclipse .aether .DefaultRepositorySystemSession ;
54
+ import org .eclipse .aether .RepositorySystemSession ;
55
+ import org .eclipse .aether .artifact .DefaultArtifact ;
56
+ import org .eclipse .aether .collection .CollectRequest ;
57
+ import org .eclipse .aether .graph .Dependency ;
58
+ import org .eclipse .aether .repository .RemoteRepository ;
59
+ import org .eclipse .aether .resolution .ArtifactResult ;
60
+ import org .eclipse .aether .resolution .DependencyRequest ;
61
+ import org .eclipse .aether .resolution .DependencyResolutionException ;
62
+ import org .eclipse .aether .resolution .DependencyResult ;
53
63
import org .graalvm .buildtools .utils .NativeImageConfigurationUtils ;
54
- import org .graalvm .junit .platform .JUnitPlatformFeature ;
55
64
56
- import java .io .File ;
57
65
import java .io .IOException ;
58
66
import java .io .UncheckedIOException ;
59
- import java .net .URISyntaxException ;
60
67
import java .nio .file .Files ;
61
68
import java .nio .file .Path ;
62
69
import java .nio .file .Paths ;
63
70
import java .util .ArrayList ;
64
71
import java .util .Arrays ;
72
+ import java .util .Collections ;
65
73
import java .util .HashMap ;
74
+ import java .util .HashSet ;
66
75
import java .util .List ;
67
- import java .util .Optional ;
76
+ import java .util .Set ;
77
+ import java .util .stream .Collectors ;
68
78
import java .util .stream .Stream ;
69
79
70
80
import static org .graalvm .buildtools .utils .NativeImageConfigurationUtils .NATIVE_TESTS_EXE ;
71
81
72
82
/**
73
83
* This goal builds and runs native tests.
84
+ *
74
85
* @author Sebastien Deleuze
75
86
*/
76
87
@ Mojo (name = "test" , defaultPhase = LifecyclePhase .TEST , threadSafe = true ,
77
- requiresDependencyResolution = ResolutionScope .TEST ,
78
- requiresDependencyCollection = ResolutionScope .TEST )
88
+ requiresDependencyResolution = ResolutionScope .TEST ,
89
+ requiresDependencyCollection = ResolutionScope .TEST )
79
90
public class NativeTestMojo extends AbstractNativeImageMojo {
80
91
81
92
@ Parameter (property = "skipTests" , defaultValue = "false" )
@@ -89,31 +100,39 @@ protected void populateApplicationClasspath() throws MojoExecutionException {
89
100
super .populateApplicationClasspath ();
90
101
imageClasspath .add (Paths .get (project .getBuild ().getTestOutputDirectory ()));
91
102
project .getBuild ()
92
- .getTestResources ()
93
- .stream ()
94
- .map (FileSet ::getDirectory )
95
- .map (Paths ::get )
96
- .forEach (imageClasspath ::add );
103
+ .getTestResources ()
104
+ .stream ()
105
+ .map (FileSet ::getDirectory )
106
+ .map (Paths ::get )
107
+ .forEach (imageClasspath ::add );
97
108
}
98
109
99
110
@ Override
100
111
protected List <String > getDependencyScopes () {
101
112
return Arrays .asList (
102
- Artifact .SCOPE_COMPILE ,
103
- Artifact .SCOPE_RUNTIME ,
104
- Artifact .SCOPE_TEST ,
105
- Artifact .SCOPE_COMPILE_PLUS_RUNTIME
113
+ Artifact .SCOPE_COMPILE ,
114
+ Artifact .SCOPE_RUNTIME ,
115
+ Artifact .SCOPE_TEST ,
116
+ Artifact .SCOPE_COMPILE_PLUS_RUNTIME
106
117
);
107
118
}
108
119
109
120
@ Override
110
121
protected void addDependenciesToClasspath () throws MojoExecutionException {
111
122
super .addDependenciesToClasspath ();
123
+ Set <Module > modules = new HashSet <>();
124
+ //noinspection SimplifyStreamApiCallChains
112
125
pluginArtifacts .stream ()
113
- .filter (it -> it .getGroupId ().startsWith (NativeImageConfigurationUtils .MAVEN_GROUP_ID ) || it .getGroupId ().startsWith ("org.junit" ))
114
- .map (it -> it .getFile ().toPath ())
115
- .forEach (imageClasspath ::add );
116
- findNativePlatformJar ().ifPresent (imageClasspath ::add );
126
+ // do not use peek as Stream implementations are free to discard it
127
+ .map (a -> {
128
+ modules .add (new Module (a .getGroupId (), a .getArtifactId ()));
129
+ return a ;
130
+ })
131
+ .filter (it -> it .getGroupId ().startsWith (NativeImageConfigurationUtils .MAVEN_GROUP_ID ) || it .getGroupId ().startsWith ("org.junit" ))
132
+ .map (it -> it .getFile ().toPath ())
133
+ .forEach (imageClasspath ::add );
134
+ var jars = findJunitPlatformNativeJars (modules );
135
+ imageClasspath .addAll (jars );
117
136
}
118
137
119
138
@ Override
@@ -142,7 +161,7 @@ public void execute() throws MojoExecutionException {
142
161
systemProperties = new HashMap <>();
143
162
}
144
163
systemProperties .put ("junit.platform.listeners.uid.tracking.output.dir" ,
145
- NativeExtension .testIdsDirectory (outputDirectory .getAbsolutePath ()));
164
+ NativeExtension .testIdsDirectory (outputDirectory .getAbsolutePath ()));
146
165
147
166
imageName = NATIVE_TESTS_EXE ;
148
167
mainClass = "org.graalvm.junit.platform.NativeImageJUnitLauncher" ;
@@ -248,15 +267,71 @@ private static Stream<Path> findFiles(Path dir, String prefix) throws IOExceptio
248
267
return Stream .empty ();
249
268
}
250
269
return Files .find (dir , Integer .MAX_VALUE ,
251
- (path , basicFileAttributes ) -> (basicFileAttributes .isRegularFile ()
252
- && path .getFileName ().toString ().startsWith (prefix )));
270
+ (path , basicFileAttributes ) -> (basicFileAttributes .isRegularFile ()
271
+ && path .getFileName ().toString ().startsWith (prefix )));
253
272
}
254
273
255
- private static Optional <Path > findNativePlatformJar () {
274
+ private List <Path > findJunitPlatformNativeJars (Set <Module > modulesAlreadyOnClasspath ) {
275
+ RepositorySystemSession repositorySession = mavenSession .getRepositorySession ();
276
+ DefaultRepositorySystemSession newSession = new DefaultRepositorySystemSession (repositorySession );
277
+ CollectRequest collectRequest = new CollectRequest ();
278
+ List <RemoteRepository > repositories = project .getRemoteProjectRepositories ();
279
+ collectRequest .setRepositories (repositories );
280
+ DefaultArtifact artifact = new DefaultArtifact (
281
+ RuntimeMetadata .GROUP_ID ,
282
+ RuntimeMetadata .JUNIT_PLATFORM_NATIVE_ARTIFACT_ID ,
283
+ null ,
284
+ "jar" ,
285
+ RuntimeMetadata .VERSION
286
+ );
287
+ Dependency dependency = new Dependency (artifact , "runtime" );
288
+ collectRequest .addDependency (dependency );
289
+ DependencyRequest dependencyRequest = new DependencyRequest (collectRequest , null );
290
+ DependencyResult dependencyResult ;
256
291
try {
257
- return Optional .of (new File (JUnitPlatformFeature .class .getProtectionDomain ().getCodeSource ().getLocation ().toURI ()).toPath ());
258
- } catch (URISyntaxException e ) {
259
- return Optional .empty ();
292
+ dependencyResult = repositorySystem .resolveDependencies (newSession , dependencyRequest );
293
+ } catch (DependencyResolutionException e ) {
294
+ return Collections .emptyList ();
295
+ }
296
+ return dependencyResult .getArtifactResults ()
297
+ .stream ()
298
+ .map (ArtifactResult ::getArtifact )
299
+ .filter (a -> !modulesAlreadyOnClasspath .contains (new Module (a .getGroupId (), a .getArtifactId ())))
300
+ .map (a -> a .getFile ().toPath ())
301
+ .collect (Collectors .toList ());
302
+ }
303
+
304
+ private static final class Module {
305
+ private final String groupId ;
306
+ private final String artifactId ;
307
+
308
+ private Module (String groupId , String artifactId ) {
309
+ this .groupId = groupId ;
310
+ this .artifactId = artifactId ;
311
+ }
312
+
313
+ @ Override
314
+ public boolean equals (Object o ) {
315
+ if (this == o ) {
316
+ return true ;
317
+ }
318
+ if (o == null || getClass () != o .getClass ()) {
319
+ return false ;
320
+ }
321
+
322
+ Module module = (Module ) o ;
323
+
324
+ if (!groupId .equals (module .groupId )) {
325
+ return false ;
326
+ }
327
+ return artifactId .equals (module .artifactId );
328
+ }
329
+
330
+ @ Override
331
+ public int hashCode () {
332
+ int result = groupId .hashCode ();
333
+ result = 31 * result + artifactId .hashCode ();
334
+ return result ;
260
335
}
261
336
}
262
337
}
0 commit comments