1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.archiver;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.net.URI;
25 import java.net.URL;
26 import java.nio.file.Files;
27 import java.nio.file.Path;
28 import java.nio.file.Paths;
29 import java.nio.file.attribute.FileTime;
30 import java.time.Instant;
31 import java.time.format.DateTimeParseException;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collections;
35 import java.util.Comparator;
36 import java.util.HashMap;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Properties;
40 import java.util.Set;
41 import java.util.TreeSet;
42 import java.util.jar.Attributes;
43 import java.util.jar.JarFile;
44 import java.util.jar.Manifest;
45 import java.util.stream.Stream;
46 import java.util.zip.ZipEntry;
47
48 import org.apache.maven.artifact.Artifact;
49 import org.apache.maven.artifact.handler.ArtifactHandler;
50 import org.apache.maven.artifact.handler.DefaultArtifactHandler;
51 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
52 import org.apache.maven.execution.MavenSession;
53 import org.apache.maven.model.Build;
54 import org.apache.maven.model.Model;
55 import org.apache.maven.model.Organization;
56 import org.apache.maven.project.MavenProject;
57 import org.codehaus.plexus.archiver.jar.JarArchiver;
58 import org.codehaus.plexus.archiver.jar.ManifestException;
59 import org.junit.jupiter.api.Test;
60 import org.junit.jupiter.api.condition.EnabledForJreRange;
61 import org.junit.jupiter.api.condition.JRE;
62 import org.junit.jupiter.params.ParameterizedTest;
63 import org.junit.jupiter.params.provider.CsvSource;
64 import org.junit.jupiter.params.provider.EmptySource;
65 import org.junit.jupiter.params.provider.NullAndEmptySource;
66 import org.junit.jupiter.params.provider.ValueSource;
67
68 import static org.assertj.core.api.Assertions.assertThat;
69 import static org.assertj.core.api.Assertions.assertThatCode;
70 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
71 import static org.mockito.Mockito.mock;
72 import static org.mockito.Mockito.when;
73
74 class MavenArchiverTest {
75 static class ArtifactComparator implements Comparator<Artifact> {
76 public int compare(Artifact o1, Artifact o2) {
77 return o1.getArtifactId().compareTo(o2.getArtifactId());
78 }
79
80 public boolean equals(Object o) {
81 return false;
82 }
83 }
84
85 @ParameterizedTest
86 @EmptySource
87 @ValueSource(
88 strings = {
89 ".",
90 "dash-is-invalid",
91 "plus+is+invalid",
92 "colon:is:invalid",
93 "new.class",
94 "123.at.start.is.invalid",
95 "digit.at.123start.is.invalid"
96 })
97 void testInvalidModuleNames(String value) {
98 assertThat(MavenArchiver.isValidModuleName(value)).isFalse();
99 }
100
101 @ParameterizedTest
102 @ValueSource(strings = {"a", "a.b", "a_b", "trailing0.digits123.are456.ok789", "UTF8.chars.are.okay.äëïöüẍ", "ℤ€ℕ"})
103 void testValidModuleNames(String value) {
104 assertThat(MavenArchiver.isValidModuleName(value)).isTrue();
105 }
106
107 @Test
108 void testGetManifestExtensionList() throws Exception {
109 MavenArchiver archiver = new MavenArchiver();
110
111 MavenSession session = getDummySession();
112
113 Model model = new Model();
114 model.setArtifactId("dummy");
115
116 MavenProject project = new MavenProject(model);
117
118 Set<Artifact> artifacts = new TreeSet<>(new ArtifactComparator());
119 project.setArtifacts(artifacts);
120
121
122 ManifestConfiguration config = new ManifestConfiguration() {
123 public boolean isAddExtensions() {
124 return true;
125 }
126 };
127
128 Manifest manifest = archiver.getManifest(session, project, config);
129
130 assertThat(manifest.getMainAttributes()).isNotNull();
131
132 assertThat(manifest.getMainAttributes().getValue("Extension-List")).isNull();
133
134 Artifact artifact1 = mock(Artifact.class);
135 when(artifact1.getGroupId()).thenReturn("org.apache.dummy");
136 when(artifact1.getArtifactId()).thenReturn("dummy1");
137 when(artifact1.getVersion()).thenReturn("1.0");
138 when(artifact1.getType()).thenReturn("dll");
139 when(artifact1.getScope()).thenReturn("compile");
140
141 artifacts.add(artifact1);
142
143 manifest = archiver.getManifest(session, project, config);
144
145 assertThat(manifest.getMainAttributes().getValue("Extension-List")).isNull();
146
147 Artifact artifact2 = mock(Artifact.class);
148 when(artifact2.getGroupId()).thenReturn("org.apache.dummy");
149 when(artifact2.getArtifactId()).thenReturn("dummy2");
150 when(artifact2.getVersion()).thenReturn("1.0");
151 when(artifact2.getType()).thenReturn("jar");
152 when(artifact2.getScope()).thenReturn("compile");
153
154 artifacts.add(artifact2);
155
156 manifest = archiver.getManifest(session, project, config);
157
158 assertThat(manifest.getMainAttributes().getValue("Extension-List")).isEqualTo("dummy2");
159
160 Artifact artifact3 = mock(Artifact.class);
161 when(artifact3.getGroupId()).thenReturn("org.apache.dummy");
162 when(artifact3.getArtifactId()).thenReturn("dummy3");
163 when(artifact3.getVersion()).thenReturn("1.0");
164 when(artifact3.getType()).thenReturn("jar");
165 when(artifact3.getScope()).thenReturn("test");
166
167 artifacts.add(artifact3);
168
169 manifest = archiver.getManifest(session, project, config);
170
171 assertThat(manifest.getMainAttributes().getValue("Extension-List")).isEqualTo("dummy2");
172
173 Artifact artifact4 = mock(Artifact.class);
174 when(artifact4.getGroupId()).thenReturn("org.apache.dummy");
175 when(artifact4.getArtifactId()).thenReturn("dummy4");
176 when(artifact4.getVersion()).thenReturn("1.0");
177 when(artifact4.getType()).thenReturn("jar");
178 when(artifact4.getScope()).thenReturn("compile");
179
180 artifacts.add(artifact4);
181
182 manifest = archiver.getManifest(session, project, config);
183
184 assertThat(manifest.getMainAttributes().getValue("Extension-List")).isEqualTo("dummy2 dummy4");
185 }
186
187 @Test
188 void testMultiClassPath() throws Exception {
189 final File tempFile = File.createTempFile("maven-archiver-test-", ".jar");
190
191 try {
192 MavenArchiver archiver = new MavenArchiver();
193
194 MavenSession session = getDummySession();
195
196 Model model = new Model();
197 model.setArtifactId("dummy");
198
199 MavenProject project = new MavenProject(model) {
200 public List<String> getRuntimeClasspathElements() {
201 return Collections.singletonList(tempFile.getAbsolutePath());
202 }
203 };
204
205
206 ManifestConfiguration manifestConfig = new ManifestConfiguration() {
207 public boolean isAddClasspath() {
208 return true;
209 }
210 };
211
212 MavenArchiveConfiguration archiveConfiguration = new MavenArchiveConfiguration();
213 archiveConfiguration.setManifest(manifestConfig);
214 archiveConfiguration.addManifestEntry("Class-Path", "help/");
215
216 Manifest manifest = archiver.getManifest(session, project, archiveConfiguration);
217 String classPath = manifest.getMainAttributes().getValue("Class-Path");
218 assertThat(classPath)
219 .as("User specified Class-Path entry was not prepended to manifest")
220 .startsWith("help/")
221 .as("Class-Path generated by addClasspath was not appended to manifest")
222 .endsWith(tempFile.getName());
223 } finally {
224
225 tempFile.delete();
226 }
227 }
228
229 @Test
230 void testRecreation() throws Exception {
231 File jarFile = new File("target/test/dummy.jar");
232 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
233
234 MavenArchiver archiver = getMavenArchiver(jarArchiver);
235
236 MavenSession session = getDummySession();
237 MavenProject project = getDummyProject();
238
239 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
240 config.setForced(false);
241
242 Path directory = Paths.get("target", "maven-archiver");
243 if (Files.exists(directory)) {
244 try (Stream<Path> paths = Files.walk(directory)) {
245 paths.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
246 }
247 }
248
249 archiver.createArchive(session, project, config);
250 assertThat(jarFile).exists();
251
252 long history = System.currentTimeMillis() - 60000L;
253 jarFile.setLastModified(history);
254 long time = jarFile.lastModified();
255
256 try (Stream<Path> paths = Files.walk(directory)) {
257 FileTime fileTime = FileTime.fromMillis(time);
258 paths.forEach(path -> assertThatCode(() -> Files.setLastModifiedTime(path, fileTime))
259 .doesNotThrowAnyException());
260 }
261
262 archiver.createArchive(session, project, config);
263
264 config.setForced(true);
265 archiver.createArchive(session, project, config);
266
267 assertThat(jarFile.lastModified()).isGreaterThanOrEqualTo(time);
268 }
269
270 @Test
271 void testNotGenerateImplementationVersionForMANIFESTMF() throws Exception {
272 File jarFile = new File("target/test/dummy.jar");
273 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
274
275 MavenArchiver archiver = getMavenArchiver(jarArchiver);
276
277 MavenSession session = getDummySession();
278 MavenProject project = getDummyProject();
279
280 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
281 config.setForced(true);
282 config.getManifest().setAddDefaultImplementationEntries(false);
283 archiver.createArchive(session, project, config);
284 assertThat(jarFile).exists();
285
286 try (JarFile jar = new JarFile(jarFile)) {
287 assertThat(jar.getManifest().getMainAttributes())
288 .doesNotContainKey(Attributes.Name.IMPLEMENTATION_VERSION);
289 }
290 }
291
292 @Test
293 void testGenerateImplementationVersionForMANIFESTMF() throws Exception {
294 File jarFile = new File("target/test/dummy.jar");
295 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
296
297 MavenArchiver archiver = getMavenArchiver(jarArchiver);
298
299 MavenSession session = getDummySession();
300 MavenProject project = getDummyProject();
301
302 String ls = System.getProperty("line.separator");
303 project.setDescription("foo " + ls + " bar ");
304 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
305 config.setForced(true);
306 config.getManifest().setAddDefaultImplementationEntries(true);
307 config.addManifestEntry("Description", project.getDescription());
308 archiver.createArchive(session, project, config);
309 assertThat(jarFile).exists();
310
311 try (JarFile jar = new JarFile(jarFile)) {
312 assertThat(jar.getManifest().getMainAttributes())
313 .containsKey(Attributes.Name.IMPLEMENTATION_VERSION)
314 .containsEntry(Attributes.Name.IMPLEMENTATION_VERSION, "0.1.1");
315 }
316 }
317
318 private MavenArchiver getMavenArchiver(JarArchiver jarArchiver) {
319 MavenArchiver archiver = new MavenArchiver();
320 archiver.setArchiver(jarArchiver);
321 archiver.setOutputFile(jarArchiver.getDestFile());
322 return archiver;
323 }
324
325 @Test
326 void testDashesInClassPath_MSHARED_134() throws Exception {
327 File jarFile = new File("target/test/dummyWithDashes.jar");
328 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
329
330 MavenArchiver archiver = getMavenArchiver(jarArchiver);
331
332 MavenSession session = getDummySession();
333 MavenProject project = getDummyProject();
334
335 Set<Artifact> artifacts =
336 getArtifacts(getMockArtifact1(), getArtifactWithDot(), getMockArtifact2(), getMockArtifact3());
337
338 project.setArtifacts(artifacts);
339
340 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
341 config.setForced(false);
342
343 final ManifestConfiguration mftConfig = config.getManifest();
344 mftConfig.setMainClass("org.apache.maven.Foo");
345 mftConfig.setAddClasspath(true);
346 mftConfig.setAddExtensions(true);
347 mftConfig.setClasspathPrefix("./lib/");
348
349 archiver.createArchive(session, project, config);
350 assertThat(jarFile).exists();
351 }
352
353 @Test
354 void testDashesInClassPath_MSHARED_182() throws Exception {
355 File jarFile = new File("target/test/dummy.jar");
356 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
357 MavenArchiver archiver = getMavenArchiver(jarArchiver);
358
359 MavenSession session = getDummySession();
360 MavenProject project = getDummyProject();
361
362 Set<Artifact> artifacts =
363 getArtifacts(getMockArtifact1(), getArtifactWithDot(), getMockArtifact2(), getMockArtifact3());
364
365 project.setArtifacts(artifacts);
366
367 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
368 config.setForced(false);
369
370 final ManifestConfiguration mftConfig = config.getManifest();
371 mftConfig.setMainClass("org.apache.maven.Foo");
372 mftConfig.setAddClasspath(true);
373 mftConfig.setAddExtensions(true);
374 mftConfig.setClasspathPrefix("./lib/");
375 config.addManifestEntry("Key1", "value1");
376 config.addManifestEntry("key2", "value2");
377
378 archiver.createArchive(session, project, config);
379 assertThat(jarFile).exists();
380 final Attributes mainAttributes = getJarFileManifest(jarFile).getMainAttributes();
381 assertThat(mainAttributes.getValue("Key1")).isEqualTo("value1");
382 assertThat(mainAttributes.getValue("Key2")).isEqualTo("value2");
383 }
384
385 @Test
386 void testCarriageReturnInManifestEntry() throws Exception {
387 File jarFile = new File("target/test/dummy.jar");
388 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
389
390 MavenArchiver archiver = getMavenArchiver(jarArchiver);
391
392 MavenSession session = getDummySession();
393 MavenProject project = getDummyProject();
394
395 String ls = System.getProperty("line.separator");
396 project.setDescription("foo " + ls + " bar ");
397 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
398 config.setForced(true);
399 config.getManifest().setAddDefaultImplementationEntries(true);
400 config.addManifestEntry("Description", project.getDescription());
401
402
403 archiver.createArchive(session, project, config);
404 assertThat(jarFile).exists();
405
406 final Manifest manifest = getJarFileManifest(jarFile);
407 Attributes attributes = manifest.getMainAttributes();
408 assertThat(project.getDescription().indexOf(ls)).isGreaterThan(0);
409 Attributes.Name description = new Attributes.Name("Description");
410 String value = attributes.getValue(description);
411 assertThat(value).isNotNull();
412 assertThat(value.indexOf(ls)).isLessThanOrEqualTo(0);
413 }
414
415 @Test
416 void testDeprecatedCreateArchiveAPI() throws Exception {
417 File jarFile = new File("target/test/dummy.jar");
418 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
419
420 MavenArchiver archiver = getMavenArchiver(jarArchiver);
421
422 MavenProject project = getDummyProject();
423 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
424 config.setForced(true);
425 config.getManifest().setAddDefaultImplementationEntries(true);
426 config.getManifest().setAddDefaultSpecificationEntries(true);
427
428 MavenSession session = getDummySessionWithoutMavenVersion();
429 archiver.createArchive(session, project, config);
430 assertThat(jarFile).exists();
431 Attributes manifest = getJarFileManifest(jarFile).getMainAttributes();
432
433
434 assertThat(manifest)
435 .containsEntry(new Attributes.Name("Created-By"), "Maven Archiver")
436 .containsEntry(Attributes.Name.SPECIFICATION_TITLE, "archiver test")
437 .containsEntry(Attributes.Name.SPECIFICATION_VERSION, "0.1")
438 .containsEntry(Attributes.Name.SPECIFICATION_VENDOR, "Apache")
439 .containsEntry(Attributes.Name.IMPLEMENTATION_TITLE, "archiver test")
440 .containsEntry(Attributes.Name.IMPLEMENTATION_VERSION, "0.1.1")
441 .containsEntry(Attributes.Name.IMPLEMENTATION_VENDOR, "Apache")
442 .containsEntry(new Attributes.Name("Build-Jdk-Spec"), System.getProperty("java.specification.version"));
443 }
444
445 @Test
446 void testMinimalManifestEntries() throws Exception {
447 File jarFile = new File("target/test/dummy.jar");
448 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
449
450 MavenArchiver archiver = getMavenArchiver(jarArchiver);
451
452 MavenSession session = getDummySession();
453 MavenProject project = getDummyProject();
454 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
455 config.setForced(true);
456 config.getManifest().setAddDefaultEntries(false);
457
458 archiver.createArchive(session, project, config);
459 assertThat(jarFile).exists();
460
461 final Manifest jarFileManifest = getJarFileManifest(jarFile);
462 Attributes manifest = jarFileManifest.getMainAttributes();
463
464 assertThat(manifest).hasSize(1).containsOnlyKeys(new Attributes.Name("Manifest-Version"));
465 assertThat(manifest.getValue("Manifest-Version")).isEqualTo("1.0");
466 }
467
468 @Test
469 void testManifestEntries() throws Exception {
470 File jarFile = new File("target/test/dummy.jar");
471 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
472
473 MavenArchiver archiver = getMavenArchiver(jarArchiver);
474
475 MavenSession session = getDummySession();
476 MavenProject project = getDummyProject();
477 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
478 config.setForced(true);
479 config.getManifest().setAddDefaultImplementationEntries(true);
480 config.getManifest().setAddDefaultSpecificationEntries(true);
481 config.getManifest().setAddBuildEnvironmentEntries(true);
482
483 Map<String, String> manifestEntries = new HashMap<>();
484 manifestEntries.put("foo", "bar");
485 manifestEntries.put("first-name", "olivier");
486 manifestEntries.put("Automatic-Module-Name", "org.apache.maven.archiver");
487 manifestEntries.put("keyWithEmptyValue", null);
488 config.setManifestEntries(manifestEntries);
489
490 ManifestSection manifestSection = new ManifestSection();
491 manifestSection.setName("UserSection");
492 manifestSection.addManifestEntry("key", "value");
493 List<ManifestSection> manifestSections = new ArrayList<>();
494 manifestSections.add(manifestSection);
495 config.setManifestSections(manifestSections);
496 config.getManifest().setMainClass("org.apache.maven.Foo");
497 archiver.createArchive(session, project, config);
498 assertThat(jarFile).exists();
499
500 final Manifest jarFileManifest = getJarFileManifest(jarFile);
501 Attributes manifest = jarFileManifest.getMainAttributes();
502
503
504 assertThat(manifest)
505 .containsEntry(new Attributes.Name("Created-By"), "Maven Archiver")
506 .containsEntry(
507 new Attributes.Name("Build-Tool"),
508 session.getSystemProperties().get("maven.build.version"))
509 .containsEntry(
510 new Attributes.Name("Build-Jdk"),
511 String.format("%s (%s)", System.getProperty("java.version"), System.getProperty("java.vendor")))
512 .containsEntry(
513 new Attributes.Name("Build-Os"),
514 String.format(
515 "%s (%s; %s)",
516 System.getProperty("os.name"),
517 System.getProperty("os.version"),
518 System.getProperty("os.arch")))
519 .containsEntry(Attributes.Name.SPECIFICATION_TITLE, "archiver test")
520 .containsEntry(Attributes.Name.SPECIFICATION_VERSION, "0.1")
521 .containsEntry(Attributes.Name.SPECIFICATION_VENDOR, "Apache")
522 .containsEntry(Attributes.Name.IMPLEMENTATION_TITLE, "archiver test")
523 .containsEntry(Attributes.Name.IMPLEMENTATION_VERSION, "0.1.1")
524 .containsEntry(Attributes.Name.IMPLEMENTATION_VENDOR, "Apache")
525 .containsEntry(Attributes.Name.MAIN_CLASS, "org.apache.maven.Foo")
526 .containsEntry(new Attributes.Name("foo"), "bar")
527 .containsEntry(new Attributes.Name("first-name"), "olivier");
528
529 assertThat(manifest.getValue("Automatic-Module-Name")).isEqualTo("org.apache.maven.archiver");
530
531 assertThat(manifest)
532 .containsEntry(new Attributes.Name("Build-Jdk-Spec"), System.getProperty("java.specification.version"));
533
534 assertThat(manifest.getValue(new Attributes.Name("keyWithEmptyValue"))).isEmpty();
535 assertThat(manifest).containsKey(new Attributes.Name("keyWithEmptyValue"));
536
537 manifest = jarFileManifest.getAttributes("UserSection");
538
539 assertThat(manifest).containsEntry(new Attributes.Name("key"), "value");
540 }
541
542 @Test
543 void testManifestWithInvalidAutomaticModuleNameThrowsOnCreateArchive() throws Exception {
544 File jarFile = new File("target/test/dummy.jar");
545 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
546
547 MavenArchiver archiver = getMavenArchiver(jarArchiver);
548
549 MavenSession session = getDummySession();
550 MavenProject project = getDummyProject();
551 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
552
553 Map<String, String> manifestEntries = new HashMap<>();
554 manifestEntries.put("Automatic-Module-Name", "123.in-valid.new.name");
555 config.setManifestEntries(manifestEntries);
556
557 try {
558 archiver.createArchive(session, project, config);
559 } catch (ManifestException e) {
560 assertThat(e.getMessage()).isEqualTo("Invalid automatic module name: '123.in-valid.new.name'");
561 }
562 }
563
564
565
566
567 @Test
568 void testManifestSections() throws Exception {
569 MavenArchiver archiver = new MavenArchiver();
570
571 MavenSession session = getDummySession();
572
573 MavenProject project = getDummyProject();
574 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
575
576 ManifestSection manifestSection = new ManifestSection();
577 manifestSection.setName("SectionOne");
578 manifestSection.addManifestEntry("key", "value");
579 List<ManifestSection> manifestSections = new ArrayList<>();
580 manifestSections.add(manifestSection);
581 config.setManifestSections(manifestSections);
582
583 Manifest manifest = archiver.getManifest(session, project, config);
584
585 Attributes section = manifest.getAttributes("SectionOne");
586 assertThat(section)
587 .as("The section is not present in the manifest as it should be.")
588 .isNotNull();
589
590 String attribute = section.getValue("key");
591 assertThat(attribute)
592 .as("The attribute we are looking for is not present in the section.")
593 .isNotNull()
594 .as("The value of the attribute is wrong.")
595 .isEqualTo("value");
596 }
597
598 @Test
599 void testDefaultClassPathValue() throws Exception {
600 MavenSession session = getDummySession();
601 MavenProject project = getDummyProject();
602 File jarFile = new File("target/test/dummy.jar");
603 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
604
605 MavenArchiver archiver = getMavenArchiver(jarArchiver);
606
607 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
608 config.setForced(true);
609 config.getManifest().setAddDefaultImplementationEntries(true);
610 config.getManifest().setAddDefaultSpecificationEntries(true);
611 config.getManifest().setMainClass("org.apache.maven.Foo");
612 config.getManifest().setAddClasspath(true);
613 config.getManifest().setClasspathLayoutType(ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_CUSTOM);
614 config.getManifest()
615 .setCustomClasspathLayout(
616 "${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}");
617 archiver.createArchive(session, project, config);
618 assertThat(jarFile).exists();
619 final Manifest manifest = getJarFileManifest(jarFile);
620 String classPath = manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
621 assertThat(classPath).isNotNull();
622 assertThat(classPath.split(" "))
623 .containsExactly("dummy1-1.0.jar", "dummy2-1.5.jar", "dummy3-2.0-classifier.jar");
624 }
625
626 private void deleteAndAssertNotPresent(File jarFile) {
627 jarFile.delete();
628 assertThat(jarFile).doesNotExist();
629 }
630
631 @Test
632 void testDefaultClassPathValue_WithSnapshot() throws Exception {
633 MavenSession session = getDummySession();
634 MavenProject project = getDummyProjectWithSnapshot();
635 File jarFile = new File("target/test/dummy.jar");
636 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
637
638 MavenArchiver archiver = getMavenArchiver(jarArchiver);
639
640 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
641 config.setForced(true);
642 config.getManifest().setAddDefaultImplementationEntries(true);
643 config.getManifest().setAddDefaultSpecificationEntries(true);
644 config.getManifest().setMainClass("org.apache.maven.Foo");
645 config.getManifest().setAddClasspath(true);
646 config.getManifest().setClasspathLayoutType(ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_CUSTOM);
647 config.getManifest()
648 .setCustomClasspathLayout(
649 "${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}");
650 archiver.createArchive(session, project, config);
651 assertThat(jarFile).exists();
652
653 final Manifest manifest = getJarFileManifest(jarFile);
654 String classPath = manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
655 assertThat(classPath).isNotNull();
656 assertThat(classPath.split(" "))
657 .containsExactly("dummy1-1.1-20081022.112233-1.jar", "dummy2-1.5.jar", "dummy3-2.0-classifier.jar");
658 }
659
660 @Test
661 void testMavenRepoClassPathValue() throws Exception {
662 MavenSession session = getDummySession();
663 MavenProject project = getDummyProject();
664 File jarFile = new File("target/test/dummy.jar");
665 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
666
667 MavenArchiver archiver = getMavenArchiver(jarArchiver);
668
669 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
670 config.setForced(true);
671 config.getManifest().setAddDefaultImplementationEntries(true);
672 config.getManifest().setAddDefaultSpecificationEntries(true);
673 config.getManifest().setMainClass("org.apache.maven.Foo");
674 config.getManifest().setAddClasspath(true);
675 config.getManifest().setUseUniqueVersions(true);
676 config.getManifest().setClasspathLayoutType(ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_REPOSITORY);
677 archiver.createArchive(session, project, config);
678 assertThat(jarFile).exists();
679 Manifest manifest = archiver.getManifest(session, project, config);
680 String[] classPathEntries =
681 new String(manifest.getMainAttributes().getValue("Class-Path").getBytes()).split(" ");
682 assertThat(classPathEntries)
683 .containsExactly(
684 "org/apache/dummy/dummy1/1.0.1/dummy1-1.0.jar",
685 "org/apache/dummy/foo/dummy2/1.5/dummy2-1.5.jar",
686 "org/apache/dummy/bar/dummy3/2.0/dummy3-2.0-classifier.jar");
687
688 String classPath = getJarFileManifest(jarFile).getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
689 assertThat(classPath).isNotNull();
690 assertThat(classPath.split(" "))
691 .containsExactly(
692 "org/apache/dummy/dummy1/1.0.1/dummy1-1.0.jar",
693 "org/apache/dummy/foo/dummy2/1.5/dummy2-1.5.jar",
694 "org/apache/dummy/bar/dummy3/2.0/dummy3-2.0-classifier.jar");
695 }
696
697 @Test
698 void shouldCreateArchiveWithSimpleClassPathLayoutWhileSettingSimpleLayoutExplicit() throws Exception {
699 MavenSession session = getDummySession();
700 MavenProject project = getDummyProject();
701 File jarFile = new File("target/test/dummy-explicit-simple.jar");
702 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
703
704 MavenArchiver archiver = getMavenArchiver(jarArchiver);
705
706 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
707 config.setForced(true);
708 config.getManifest().setAddDefaultImplementationEntries(true);
709 config.getManifest().setAddDefaultSpecificationEntries(true);
710 config.getManifest().setMainClass("org.apache.maven.Foo");
711 config.getManifest().setAddClasspath(true);
712 config.getManifest().setClasspathPrefix("lib");
713 config.getManifest().setClasspathLayoutType(ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_SIMPLE);
714
715 archiver.createArchive(session, project, config);
716 assertThat(jarFile).exists();
717 Manifest manifest = archiver.getManifest(session, project, config);
718 String[] classPathEntries =
719 new String(manifest.getMainAttributes().getValue("Class-Path").getBytes()).split(" ");
720 assertThat(classPathEntries)
721 .containsExactly("lib/dummy1-1.0.jar", "lib/dummy2-1.5.jar", "lib/dummy3-2.0-classifier.jar");
722
723 String classPath = getJarFileManifest(jarFile).getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
724
725 assertThat(classPath).isNotNull();
726 assertThat(classPath.split(" "))
727 .containsExactly("lib/dummy1-1.0.jar", "lib/dummy2-1.5.jar", "lib/dummy3-2.0-classifier.jar");
728 }
729
730 @Test
731 void shouldCreateArchiveCustomerLayoutSimple() throws Exception {
732 MavenSession session = getDummySession();
733 MavenProject project = getDummyProject();
734 File jarFile = new File("target/test/dummy-custom-layout-simple.jar");
735 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
736
737 MavenArchiver archiver = getMavenArchiver(jarArchiver);
738
739 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
740 config.setForced(true);
741 config.getManifest().setAddDefaultImplementationEntries(true);
742 config.getManifest().setAddDefaultSpecificationEntries(true);
743 config.getManifest().setMainClass("org.apache.maven.Foo");
744 config.getManifest().setAddClasspath(true);
745 config.getManifest().setClasspathPrefix("lib");
746 config.getManifest().setClasspathLayoutType(ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_CUSTOM);
747 config.getManifest().setCustomClasspathLayout(MavenArchiver.SIMPLE_LAYOUT);
748
749 archiver.createArchive(session, project, config);
750 assertThat(jarFile).exists();
751 Manifest manifest = archiver.getManifest(session, project, config);
752 String[] classPathEntries =
753 new String(manifest.getMainAttributes().getValue("Class-Path").getBytes()).split(" ");
754 assertThat(classPathEntries)
755 .containsExactly("lib/dummy1-1.0.jar", "lib/dummy2-1.5.jar", "lib/dummy3-2.0-classifier.jar");
756
757 String classPath = getJarFileManifest(jarFile).getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
758
759 assertThat(classPath).isNotNull();
760 assertThat(classPath.split(" "))
761 .containsExactly("lib/dummy1-1.0.jar", "lib/dummy2-1.5.jar", "lib/dummy3-2.0-classifier.jar");
762 }
763
764 @Test
765 void shouldCreateArchiveCustomLayoutSimpleNonUnique() throws Exception {
766 MavenSession session = getDummySession();
767 MavenProject project = getDummyProject();
768 File jarFile = new File("target/test/dummy-custom-layout-simple-non-unique.jar");
769 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
770
771 MavenArchiver archiver = getMavenArchiver(jarArchiver);
772
773 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
774 config.setForced(true);
775 config.getManifest().setAddDefaultImplementationEntries(true);
776 config.getManifest().setAddDefaultSpecificationEntries(true);
777 config.getManifest().setMainClass("org.apache.maven.Foo");
778 config.getManifest().setAddClasspath(true);
779 config.getManifest().setClasspathPrefix("lib");
780 config.getManifest().setClasspathLayoutType(ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_CUSTOM);
781 config.getManifest().setCustomClasspathLayout(MavenArchiver.SIMPLE_LAYOUT_NONUNIQUE);
782
783 archiver.createArchive(session, project, config);
784 assertThat(jarFile).exists();
785 Manifest manifest = archiver.getManifest(session, project, config);
786 String[] classPathEntries =
787 new String(manifest.getMainAttributes().getValue("Class-Path").getBytes()).split(" ");
788 assertThat(classPathEntries)
789 .containsExactly("lib/dummy1-1.0.1.jar", "lib/dummy2-1.5.jar", "lib/dummy3-2.0-classifier.jar");
790
791 String classPath = getJarFileManifest(jarFile).getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
792
793 assertThat(classPath).isNotNull();
794 assertThat(classPath.split(" "))
795 .containsExactly("lib/dummy1-1.0.1.jar", "lib/dummy2-1.5.jar", "lib/dummy3-2.0-classifier.jar");
796 }
797
798 @Test
799 void shouldCreateArchiveCustomLayoutRepository() throws Exception {
800 MavenSession session = getDummySession();
801 MavenProject project = getDummyProject();
802 File jarFile = new File("target/test/dummy-custom-layout-repo.jar");
803 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
804
805 MavenArchiver archiver = getMavenArchiver(jarArchiver);
806
807 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
808 config.setForced(true);
809 config.getManifest().setAddDefaultImplementationEntries(true);
810 config.getManifest().setAddDefaultSpecificationEntries(true);
811 config.getManifest().setMainClass("org.apache.maven.Foo");
812 config.getManifest().setAddClasspath(true);
813 config.getManifest().setClasspathPrefix("lib");
814 config.getManifest().setClasspathLayoutType(ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_CUSTOM);
815 config.getManifest().setCustomClasspathLayout(MavenArchiver.REPOSITORY_LAYOUT);
816
817 archiver.createArchive(session, project, config);
818 assertThat(jarFile).exists();
819 Manifest manifest = archiver.getManifest(session, project, config);
820 String[] classPathEntries =
821 new String(manifest.getMainAttributes().getValue("Class-Path").getBytes()).split(" ");
822 assertThat(classPathEntries)
823 .containsExactly(
824 "lib/org/apache/dummy/dummy1/1.0.1/dummy1-1.0.jar",
825 "lib/org/apache/dummy/foo/dummy2/1.5/dummy2-1.5.jar",
826 "lib/org/apache/dummy/bar/dummy3/2.0/dummy3-2.0-classifier.jar");
827
828 String classPath = getJarFileManifest(jarFile).getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
829
830 assertThat(classPath).isNotNull();
831 assertThat(classPath.split(" "))
832 .containsExactly(
833 "lib/org/apache/dummy/dummy1/1.0.1/dummy1-1.0.jar",
834 "lib/org/apache/dummy/foo/dummy2/1.5/dummy2-1.5.jar",
835 "lib/org/apache/dummy/bar/dummy3/2.0/dummy3-2.0-classifier.jar");
836 }
837
838 @Test
839 void shouldCreateArchiveCustomLayoutRepositoryNonUnique() throws Exception {
840 MavenSession session = getDummySession();
841 MavenProject project = getDummyProject();
842 File jarFile = new File("target/test/dummy-custom-layout-repo-non-unique.jar");
843 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
844
845 MavenArchiver archiver = getMavenArchiver(jarArchiver);
846
847 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
848 config.setForced(true);
849 config.getManifest().setAddDefaultImplementationEntries(true);
850 config.getManifest().setAddDefaultSpecificationEntries(true);
851 config.getManifest().setMainClass("org.apache.maven.Foo");
852 config.getManifest().setAddClasspath(true);
853 config.getManifest().setClasspathPrefix("lib");
854 config.getManifest().setClasspathLayoutType(ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_CUSTOM);
855 config.getManifest().setCustomClasspathLayout(MavenArchiver.REPOSITORY_LAYOUT_NONUNIQUE);
856
857 archiver.createArchive(session, project, config);
858 assertThat(jarFile).exists();
859 Manifest manifest = archiver.getManifest(session, project, config);
860 String[] classPathEntries =
861 new String(manifest.getMainAttributes().getValue("Class-Path").getBytes()).split(" ");
862 assertThat(classPathEntries)
863 .containsExactly(
864 "lib/org/apache/dummy/dummy1/1.0.1/dummy1-1.0.1.jar",
865 "lib/org/apache/dummy/foo/dummy2/1.5/dummy2-1.5.jar",
866 "lib/org/apache/dummy/bar/dummy3/2.0/dummy3-2.0-classifier.jar");
867
868 String classPath = getJarFileManifest(jarFile).getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
869
870 assertThat(classPath).isNotNull();
871 assertThat(classPath.split(" "))
872 .containsExactly(
873 "lib/org/apache/dummy/dummy1/1.0.1/dummy1-1.0.1.jar",
874 "lib/org/apache/dummy/foo/dummy2/1.5/dummy2-1.5.jar",
875 "lib/org/apache/dummy/bar/dummy3/2.0/dummy3-2.0-classifier.jar");
876 }
877
878 @Test
879 void shouldCreateArchiveWithSimpleClassPathLayoutUsingDefaults() throws Exception {
880 MavenSession session = getDummySession();
881 MavenProject project = getDummyProject();
882 File jarFile = new File("target/test/dummy-defaults.jar");
883 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
884
885 MavenArchiver archiver = getMavenArchiver(jarArchiver);
886
887 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
888 config.setForced(true);
889 config.getManifest().setAddDefaultImplementationEntries(true);
890 config.getManifest().setAddDefaultSpecificationEntries(true);
891 config.getManifest().setMainClass("org.apache.maven.Foo");
892 config.getManifest().setAddClasspath(true);
893 config.getManifest().setClasspathPrefix("lib");
894
895 archiver.createArchive(session, project, config);
896 assertThat(jarFile).exists();
897 Manifest manifest = archiver.getManifest(session, project, config);
898 String[] classPathEntries =
899 new String(manifest.getMainAttributes().getValue("Class-Path").getBytes()).split(" ");
900 assertThat(classPathEntries)
901 .containsExactly("lib/dummy1-1.0.jar", "lib/dummy2-1.5.jar", "lib/dummy3-2.0-classifier.jar");
902
903 String classPath = getJarFileManifest(jarFile).getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
904 assertThat(classPath).isNotNull();
905 assertThat(classPath.split(" "))
906 .containsExactly("lib/dummy1-1.0.jar", "lib/dummy2-1.5.jar", "lib/dummy3-2.0-classifier.jar");
907 }
908
909 @Test
910 void testMavenRepoClassPathValue_WithSnapshot() throws Exception {
911 MavenSession session = getDummySession();
912 MavenProject project = getDummyProjectWithSnapshot();
913 File jarFile = new File("target/test/dummy.jar");
914 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
915
916 MavenArchiver archiver = getMavenArchiver(jarArchiver);
917
918 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
919 config.setForced(true);
920 config.getManifest().setAddDefaultImplementationEntries(true);
921 config.getManifest().setAddDefaultSpecificationEntries(true);
922 config.getManifest().setMainClass("org.apache.maven.Foo");
923 config.getManifest().setAddClasspath(true);
924 config.getManifest().setClasspathLayoutType(ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_REPOSITORY);
925 archiver.createArchive(session, project, config);
926 assertThat(jarFile).exists();
927
928 Manifest manifest = archiver.getManifest(session, project, config);
929 String[] classPathEntries =
930 new String(manifest.getMainAttributes().getValue("Class-Path").getBytes()).split(" ");
931 assertThat(classPathEntries)
932 .containsExactly(
933 "org/apache/dummy/dummy1/1.1-SNAPSHOT/dummy1-1.1-20081022.112233-1.jar",
934 "org/apache/dummy/foo/dummy2/1.5/dummy2-1.5.jar",
935 "org/apache/dummy/bar/dummy3/2.0/dummy3-2.0-classifier.jar");
936
937 String classPath = getJarFileManifest(jarFile).getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
938 assertThat(classPath).isNotNull();
939 assertThat(classPath.split(" "))
940 .containsExactly(
941 "org/apache/dummy/dummy1/1.1-SNAPSHOT/dummy1-1.1-20081022.112233-1.jar",
942 "org/apache/dummy/foo/dummy2/1.5/dummy2-1.5.jar",
943 "org/apache/dummy/bar/dummy3/2.0/dummy3-2.0-classifier.jar");
944 }
945
946 @Test
947 void testCustomClassPathValue() throws Exception {
948 MavenSession session = getDummySession();
949 MavenProject project = getDummyProject();
950 File jarFile = new File("target/test/dummy.jar");
951 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
952
953 MavenArchiver archiver = getMavenArchiver(jarArchiver);
954
955 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
956 config.setForced(true);
957 config.getManifest().setAddDefaultImplementationEntries(true);
958 config.getManifest().setAddDefaultSpecificationEntries(true);
959 config.getManifest().setMainClass("org.apache.maven.Foo");
960 config.getManifest().setAddClasspath(true);
961 config.getManifest().setClasspathLayoutType(ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_CUSTOM);
962 config.getManifest()
963 .setCustomClasspathLayout(
964 "${artifact.groupIdPath}/${artifact.artifactId}/${artifact.version}/TEST-${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}");
965 archiver.createArchive(session, project, config);
966 assertThat(jarFile).exists();
967 Manifest manifest = archiver.getManifest(session, project, config);
968 String[] classPathEntries =
969 new String(manifest.getMainAttributes().getValue("Class-Path").getBytes()).split(" ");
970 assertThat(classPathEntries)
971 .containsExactly(
972 "org/apache/dummy/dummy1/1.0/TEST-dummy1-1.0.jar",
973 "org/apache/dummy/foo/dummy2/1.5/TEST-dummy2-1.5.jar",
974 "org/apache/dummy/bar/dummy3/2.0/TEST-dummy3-2.0-classifier.jar");
975
976 final Manifest manifest1 = getJarFileManifest(jarFile);
977 String classPath = manifest1.getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
978 assertThat(classPath).isNotNull();
979 assertThat(classPath.split(" "))
980 .containsExactly(
981 "org/apache/dummy/dummy1/1.0/TEST-dummy1-1.0.jar",
982 "org/apache/dummy/foo/dummy2/1.5/TEST-dummy2-1.5.jar",
983 "org/apache/dummy/bar/dummy3/2.0/TEST-dummy3-2.0-classifier.jar");
984 }
985
986 @Test
987 void testCustomClassPathValue_WithSnapshotResolvedVersion() throws Exception {
988 MavenSession session = getDummySession();
989 MavenProject project = getDummyProjectWithSnapshot();
990 File jarFile = new File("target/test/dummy.jar");
991 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
992 MavenArchiver archiver = getMavenArchiver(jarArchiver);
993
994 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
995 config.setForced(true);
996 config.getManifest().setAddDefaultImplementationEntries(true);
997 config.getManifest().setAddDefaultSpecificationEntries(true);
998 config.getManifest().setMainClass("org.apache.maven.Foo");
999 config.getManifest().setAddClasspath(true);
1000 config.getManifest().setClasspathLayoutType(ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_CUSTOM);
1001 config.getManifest()
1002 .setCustomClasspathLayout(
1003 "${artifact.groupIdPath}/${artifact.artifactId}/${artifact.baseVersion}/TEST-${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}");
1004 archiver.createArchive(session, project, config);
1005 assertThat(jarFile).exists();
1006
1007 Manifest manifest = archiver.getManifest(session, project, config);
1008 String[] classPathEntries =
1009 new String(manifest.getMainAttributes().getValue("Class-Path").getBytes()).split(" ");
1010 assertThat(classPathEntries)
1011 .containsExactly(
1012 "org/apache/dummy/dummy1/1.1-SNAPSHOT/TEST-dummy1-1.1-20081022.112233-1.jar",
1013 "org/apache/dummy/foo/dummy2/1.5/TEST-dummy2-1.5.jar",
1014 "org/apache/dummy/bar/dummy3/2.0/TEST-dummy3-2.0-classifier.jar");
1015
1016 String classPath = getJarFileManifest(jarFile).getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
1017 assertThat(classPath).isNotNull();
1018 assertThat(classPath.split(" "))
1019 .containsExactly(
1020 "org/apache/dummy/dummy1/1.1-SNAPSHOT/TEST-dummy1-1.1-20081022.112233-1.jar",
1021 "org/apache/dummy/foo/dummy2/1.5/TEST-dummy2-1.5.jar",
1022 "org/apache/dummy/bar/dummy3/2.0/TEST-dummy3-2.0-classifier.jar");
1023 }
1024
1025 @Test
1026 void testCustomClassPathValue_WithSnapshotForcingBaseVersion() throws Exception {
1027 MavenSession session = getDummySession();
1028 MavenProject project = getDummyProjectWithSnapshot();
1029 File jarFile = new File("target/test/dummy.jar");
1030 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
1031
1032 MavenArchiver archiver = getMavenArchiver(jarArchiver);
1033
1034 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
1035 config.setForced(true);
1036 config.getManifest().setAddDefaultImplementationEntries(true);
1037 config.getManifest().setAddDefaultSpecificationEntries(true);
1038 config.getManifest().setMainClass("org.apache.maven.Foo");
1039 config.getManifest().setAddClasspath(true);
1040 config.getManifest().setClasspathLayoutType(ManifestConfiguration.CLASSPATH_LAYOUT_TYPE_CUSTOM);
1041 config.getManifest()
1042 .setCustomClasspathLayout(
1043 "${artifact.groupIdPath}/${artifact.artifactId}/${artifact.baseVersion}/TEST-${artifact.artifactId}-${artifact.baseVersion}${dashClassifier?}.${artifact.extension}");
1044 archiver.createArchive(session, project, config);
1045 assertThat(jarFile).exists();
1046 Manifest manifest = archiver.getManifest(session, project, config);
1047 String[] classPathEntries =
1048 new String(manifest.getMainAttributes().getValue("Class-Path").getBytes()).split(" ");
1049 assertThat(classPathEntries[0]).isEqualTo("org/apache/dummy/dummy1/1.1-SNAPSHOT/TEST-dummy1-1.1-SNAPSHOT.jar");
1050 assertThat(classPathEntries[1]).isEqualTo("org/apache/dummy/foo/dummy2/1.5/TEST-dummy2-1.5.jar");
1051 assertThat(classPathEntries[2]).isEqualTo("org/apache/dummy/bar/dummy3/2.0/TEST-dummy3-2.0-classifier.jar");
1052
1053 String classPath = getJarFileManifest(jarFile).getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
1054 assertThat(classPath).isNotNull();
1055 assertThat(classPath.split(" "))
1056 .containsExactly(
1057 "org/apache/dummy/dummy1/1.1-SNAPSHOT/TEST-dummy1-1.1-SNAPSHOT.jar",
1058 "org/apache/dummy/foo/dummy2/1.5/TEST-dummy2-1.5.jar",
1059 "org/apache/dummy/bar/dummy3/2.0/TEST-dummy3-2.0-classifier.jar");
1060 }
1061
1062 @Test
1063 void testDefaultPomProperties() throws Exception {
1064 MavenSession session = getDummySession();
1065 MavenProject project = getDummyProject();
1066 File jarFile = new File("target/test/dummy.jar");
1067 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
1068
1069 MavenArchiver archiver = getMavenArchiver(jarArchiver);
1070
1071 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
1072 config.setForced(true);
1073 archiver.createArchive(session, project, config);
1074 assertThat(jarFile).exists();
1075
1076 final String groupId = project.getGroupId();
1077 final String artifactId = project.getArtifactId();
1078 final String version = project.getVersion();
1079
1080 JarFile virtJarFile = new JarFile(jarFile);
1081 ZipEntry pomPropertiesEntry =
1082 virtJarFile.getEntry("META-INF/maven/" + groupId + "/" + artifactId + "/pom.properties");
1083 assertThat(pomPropertiesEntry).isNotNull();
1084
1085 try (InputStream is = virtJarFile.getInputStream(pomPropertiesEntry)) {
1086 Properties p = new Properties();
1087 p.load(is);
1088
1089 assertThat(p.getProperty("groupId")).isEqualTo(groupId);
1090 assertThat(p.getProperty("artifactId")).isEqualTo(artifactId);
1091 assertThat(p.getProperty("version")).isEqualTo(version);
1092 }
1093 virtJarFile.close();
1094 }
1095
1096 @Test
1097 void testCustomPomProperties() throws Exception {
1098 MavenSession session = getDummySession();
1099 MavenProject project = getDummyProject();
1100 File jarFile = new File("target/test/dummy.jar");
1101 JarArchiver jarArchiver = getCleanJarArchiver(jarFile);
1102
1103 MavenArchiver archiver = getMavenArchiver(jarArchiver);
1104
1105 File customPomPropertiesFile = new File("src/test/resources/custom-pom.properties");
1106 MavenArchiveConfiguration config = new MavenArchiveConfiguration();
1107 config.setForced(true);
1108 config.setPomPropertiesFile(customPomPropertiesFile);
1109 archiver.createArchive(session, project, config);
1110 assertThat(jarFile).exists();
1111
1112 final String groupId = project.getGroupId();
1113 final String artifactId = project.getArtifactId();
1114 final String version = project.getVersion();
1115
1116 try (JarFile virtJarFile = new JarFile(jarFile)) {
1117 ZipEntry pomPropertiesEntry =
1118 virtJarFile.getEntry("META-INF/maven/" + groupId + "/" + artifactId + "/pom.properties");
1119 assertThat(pomPropertiesEntry).isNotNull();
1120
1121 try (InputStream is = virtJarFile.getInputStream(pomPropertiesEntry)) {
1122 Properties p = new Properties();
1123 p.load(is);
1124
1125 assertThat(p.getProperty("groupId")).isEqualTo(groupId);
1126 assertThat(p.getProperty("artifactId")).isEqualTo(artifactId);
1127 assertThat(p.getProperty("version")).isEqualTo(version);
1128 assertThat(p.getProperty("build.revision")).isEqualTo("1337");
1129 assertThat(p.getProperty("build.branch")).isEqualTo("tags/0.1.1");
1130 }
1131 }
1132 }
1133
1134 private JarArchiver getCleanJarArchiver(File jarFile) {
1135 deleteAndAssertNotPresent(jarFile);
1136 JarArchiver jarArchiver = new JarArchiver();
1137 jarArchiver.setDestFile(jarFile);
1138 return jarArchiver;
1139 }
1140
1141
1142
1143
1144
1145 private MavenProject getDummyProject() throws Exception {
1146 MavenProject project = getMavenProject();
1147
1148 Artifact artifact = mock(Artifact.class);
1149 when(artifact.getGroupId()).thenReturn("org.apache.dummy");
1150 when(artifact.getArtifactId()).thenReturn("dummy");
1151 when(artifact.getVersion()).thenReturn("0.1.1");
1152 when(artifact.getBaseVersion()).thenReturn("0.1.2");
1153 when(artifact.getSelectedVersion()).thenReturn(new DefaultArtifactVersion("0.1.1"));
1154 when(artifact.getType()).thenReturn("jar");
1155 when(artifact.getArtifactHandler()).thenReturn(new DefaultArtifactHandler("jar"));
1156 project.setArtifact(artifact);
1157
1158 Set<Artifact> artifacts = getArtifacts(getMockArtifact1Release(), getMockArtifact2(), getMockArtifact3());
1159 project.setArtifacts(artifacts);
1160
1161 return project;
1162 }
1163
1164 private MavenProject getMavenProject() {
1165 Model model = new Model();
1166 model.setGroupId("org.apache.dummy");
1167 model.setArtifactId("dummy");
1168 model.setVersion("0.1.1");
1169
1170 final MavenProject project = new MavenProject(model);
1171 project.setExtensionArtifacts(Collections.emptySet());
1172 project.setRemoteArtifactRepositories(Collections.emptyList());
1173 project.setPluginArtifactRepositories(Collections.emptyList());
1174 project.setName("archiver test");
1175
1176 File pomFile = new File("src/test/resources/pom.xml");
1177 project.setFile(pomFile);
1178
1179 Build build = new Build();
1180 build.setDirectory("target");
1181 build.setOutputDirectory("target");
1182 project.setBuild(build);
1183
1184 Organization organization = new Organization();
1185 organization.setName("Apache");
1186 project.setOrganization(organization);
1187 return project;
1188 }
1189
1190 private Artifact getMockArtifact3() {
1191 Artifact artifact = mock(Artifact.class);
1192 when(artifact.getGroupId()).thenReturn("org.apache.dummy.bar");
1193 when(artifact.getArtifactId()).thenReturn("dummy3");
1194 when(artifact.getVersion()).thenReturn("2.0");
1195 when(artifact.getType()).thenReturn("jar");
1196 when(artifact.getScope()).thenReturn("runtime");
1197 when(artifact.getClassifier()).thenReturn("classifier");
1198 File file = getClasspathFile(artifact.getArtifactId() + "-" + artifact.getVersion() + ".jar");
1199 when(artifact.getFile()).thenReturn(file);
1200 ArtifactHandler artifactHandler = mock(ArtifactHandler.class);
1201 when(artifactHandler.isAddedToClasspath()).thenReturn(true);
1202 when(artifactHandler.getExtension()).thenReturn("jar");
1203 when(artifact.getArtifactHandler()).thenReturn(artifactHandler);
1204 return artifact;
1205 }
1206
1207 private MavenProject getDummyProjectWithSnapshot() throws Exception {
1208 MavenProject project = getMavenProject();
1209
1210 Artifact artifact = mock(Artifact.class);
1211 when(artifact.getGroupId()).thenReturn("org.apache.dummy");
1212 when(artifact.getArtifactId()).thenReturn("dummy");
1213 when(artifact.getVersion()).thenReturn("0.1.1");
1214 when(artifact.getBaseVersion()).thenReturn("0.1.1");
1215 when(artifact.getSelectedVersion()).thenReturn(new DefaultArtifactVersion("0.1.1"));
1216 when(artifact.getType()).thenReturn("jar");
1217 when(artifact.getScope()).thenReturn("compile");
1218 when(artifact.getArtifactHandler()).thenReturn(new DefaultArtifactHandler("jar"));
1219 project.setArtifact(artifact);
1220
1221 Set<Artifact> artifacts = getArtifacts(getMockArtifact1(), getMockArtifact2(), getMockArtifact3());
1222 project.setArtifacts(artifacts);
1223
1224 return project;
1225 }
1226
1227 private Artifact getMockArtifact2() {
1228 Artifact artifact = mock(Artifact.class);
1229 when(artifact.getGroupId()).thenReturn("org.apache.dummy.foo");
1230 when(artifact.getArtifactId()).thenReturn("dummy2");
1231 when(artifact.getVersion()).thenReturn("1.5");
1232 when(artifact.getType()).thenReturn("jar");
1233 when(artifact.getScope()).thenReturn("runtime");
1234 File file = getClasspathFile(artifact.getArtifactId() + "-" + artifact.getVersion() + ".jar");
1235 when(artifact.getFile()).thenReturn(file);
1236 ArtifactHandler artifactHandler = mock(ArtifactHandler.class);
1237 when(artifactHandler.isAddedToClasspath()).thenReturn(true);
1238 when(artifactHandler.getExtension()).thenReturn("jar");
1239 when(artifact.getArtifactHandler()).thenReturn(artifactHandler);
1240 return artifact;
1241 }
1242
1243 private Artifact getArtifactWithDot() {
1244 Artifact artifact = mock(Artifact.class);
1245 when(artifact.getGroupId()).thenReturn("org.apache.dummy.foo");
1246 when(artifact.getArtifactId()).thenReturn("dummy.dot");
1247 when(artifact.getVersion()).thenReturn("1.5");
1248 when(artifact.getScope()).thenReturn("runtime");
1249 when(artifact.getArtifactHandler()).thenReturn(new DefaultArtifactHandler("jar"));
1250 return artifact;
1251 }
1252
1253 private Artifact getMockArtifact1() {
1254 Artifact artifact = mock(Artifact.class);
1255 when(artifact.getGroupId()).thenReturn("org.apache.dummy");
1256 when(artifact.getArtifactId()).thenReturn("dummy1");
1257 when(artifact.getVersion()).thenReturn("1.1-20081022.112233-1");
1258 when(artifact.getBaseVersion()).thenReturn("1.1-SNAPSHOT");
1259 when(artifact.getType()).thenReturn("jar");
1260 when(artifact.getScope()).thenReturn("runtime");
1261 File file = getClasspathFile(artifact.getArtifactId() + "-" + artifact.getVersion() + ".jar");
1262 when(artifact.getFile()).thenReturn(file);
1263 ArtifactHandler artifactHandler = mock(ArtifactHandler.class);
1264 when(artifactHandler.isAddedToClasspath()).thenReturn(true);
1265 when(artifactHandler.getExtension()).thenReturn("jar");
1266 when(artifact.getArtifactHandler()).thenReturn(artifactHandler);
1267 return artifact;
1268 }
1269
1270 private Artifact getMockArtifact1Release() {
1271 Artifact artifact = mock(Artifact.class);
1272 when(artifact.getGroupId()).thenReturn("org.apache.dummy");
1273 when(artifact.getArtifactId()).thenReturn("dummy1");
1274 when(artifact.getVersion()).thenReturn("1.0");
1275 when(artifact.getBaseVersion()).thenReturn("1.0.1");
1276 when(artifact.getType()).thenReturn("jar");
1277 when(artifact.getScope()).thenReturn("runtime");
1278 File file = getClasspathFile(artifact.getArtifactId() + "-" + artifact.getVersion() + ".jar");
1279 when(artifact.getFile()).thenReturn(file);
1280 ArtifactHandler artifactHandler = mock(ArtifactHandler.class);
1281 when(artifactHandler.isAddedToClasspath()).thenReturn(true);
1282 when(artifactHandler.getExtension()).thenReturn("jar");
1283 when(artifact.getArtifactHandler()).thenReturn(artifactHandler);
1284 return artifact;
1285 }
1286
1287 private File getClasspathFile(String file) {
1288 URL resource = Thread.currentThread().getContextClassLoader().getResource(file);
1289 if (resource == null) {
1290 throw new IllegalStateException(
1291 "Cannot retrieve java.net.URL for file: " + file + " on the current test classpath.");
1292 }
1293
1294 URI uri = new File(resource.getPath()).toURI().normalize();
1295
1296 return new File(uri.getPath().replaceAll("%20", " "));
1297 }
1298
1299 private MavenSession getDummySession() {
1300 Properties systemProperties = new Properties();
1301 systemProperties.put("maven.version", "3.1.1");
1302 systemProperties.put(
1303 "maven.build.version",
1304 "Apache Maven 3.1.1 (0728685237757ffbf44136acec0402957f723d9a; 2013-09-17 17:22:22+0200)");
1305
1306 return getDummySession(systemProperties);
1307 }
1308
1309 private MavenSession getDummySessionWithoutMavenVersion() {
1310 return getDummySession(new Properties());
1311 }
1312
1313 private MavenSession getDummySession(Properties systemProperties) {
1314 MavenSession session = mock(MavenSession.class);
1315 when(session.getSystemProperties()).thenReturn(systemProperties);
1316 return session;
1317 }
1318
1319 private Set<Artifact> getArtifacts(Artifact... artifacts) {
1320 Set<Artifact> result = new TreeSet<>(new ArtifactComparator());
1321 result.addAll(Arrays.asList(artifacts));
1322 return result;
1323 }
1324
1325 public Manifest getJarFileManifest(File jarFile) throws IOException {
1326 try (JarFile jar = new JarFile(jarFile)) {
1327 return jar.getManifest();
1328 }
1329 }
1330
1331 @Test
1332 void testParseOutputTimestamp() {
1333 MavenArchiver archiver = new MavenArchiver();
1334
1335 assertThat(archiver.parseOutputTimestamp(null)).isNull();
1336 assertThat(archiver.parseOutputTimestamp("")).isNull();
1337 assertThat(archiver.parseOutputTimestamp(".")).isNull();
1338 assertThat(archiver.parseOutputTimestamp(" ")).isNull();
1339 assertThat(archiver.parseOutputTimestamp("_")).isNull();
1340 assertThat(archiver.parseOutputTimestamp("-")).isNull();
1341 assertThat(archiver.parseOutputTimestamp("/")).isNull();
1342 assertThat(archiver.parseOutputTimestamp("!")).isNull();
1343 assertThat(archiver.parseOutputTimestamp("*")).isNull();
1344
1345 assertThat(archiver.parseOutputTimestamp("1570300662").getTime()).isEqualTo(1570300662000L);
1346 assertThat(archiver.parseOutputTimestamp("0").getTime()).isZero();
1347 assertThat(archiver.parseOutputTimestamp("1").getTime()).isEqualTo(1000L);
1348
1349 assertThat(archiver.parseOutputTimestamp("2019-10-05T18:37:42Z").getTime())
1350 .isEqualTo(1570300662000L);
1351 assertThat(archiver.parseOutputTimestamp("2019-10-05T20:37:42+02:00").getTime())
1352 .isEqualTo(1570300662000L);
1353 assertThat(archiver.parseOutputTimestamp("2019-10-05T16:37:42-02:00").getTime())
1354 .isEqualTo(1570300662000L);
1355
1356
1357
1358
1359
1360 assertThatExceptionOfType(IllegalArgumentException.class)
1361 .isThrownBy(() -> archiver.parseOutputTimestamp("2019-10-05T20:37:42+0200"));
1362 assertThatExceptionOfType(IllegalArgumentException.class)
1363 .isThrownBy(() -> archiver.parseOutputTimestamp("2019-10-05T20:37:42-0200"));
1364 }
1365
1366 @ParameterizedTest
1367 @NullAndEmptySource
1368 @ValueSource(strings = {".", " ", "_", "-", "T", "/", "!", "!", "*", "ñ"})
1369 void testEmptyParseOutputTimestampInstant(String value) {
1370
1371 assertThat(MavenArchiver.parseBuildOutputTimestamp(value)).isEmpty();
1372 }
1373
1374 @ParameterizedTest
1375 @CsvSource({
1376 "0,0",
1377 "1,1",
1378 "9,9",
1379 "1570300662,1570300662",
1380 "2147483648,2147483648",
1381 "2019-10-05T18:37:42Z,1570300662",
1382 "2019-10-05T20:37:42+02:00,1570300662",
1383 "2019-10-05T16:37:42-02:00,1570300662",
1384 "1988-02-22T15:23:47.76598Z,572541827",
1385 "2011-12-03T10:15:30+01:00,1322903730",
1386 "1980-01-01T00:00:02Z,315532802",
1387 "2099-12-31T23:59:59Z,4102444799"
1388 })
1389 void testParseOutputTimestampInstant(String value, long expected) {
1390 assertThat(MavenArchiver.parseBuildOutputTimestamp(value)).contains(Instant.ofEpochSecond(expected));
1391 }
1392
1393 @ParameterizedTest
1394 @ValueSource(
1395 strings = {
1396 "2019-10-05T20:37:42+0200",
1397 "2019-10-05T20:37:42-0200",
1398 "2019-10-05T25:00:00Z",
1399 "2019-10-05",
1400 "XYZ",
1401 "Tue, 3 Jun 2008 11:05:30 GMT",
1402 "2011-12-03T10:15:30+01:00[Europe/Paris]"
1403 })
1404 void testThrownParseOutputTimestampInstant(String outputTimestamp) {
1405
1406 assertThatExceptionOfType(IllegalArgumentException.class)
1407 .isThrownBy(() -> MavenArchiver.parseBuildOutputTimestamp(outputTimestamp))
1408 .withCauseInstanceOf(DateTimeParseException.class);
1409 }
1410
1411 @ParameterizedTest
1412 @ValueSource(
1413 strings = {
1414 "1980-01-01T00:00:01Z",
1415 "2100-01-01T00:00Z",
1416 "2100-02-28T23:59:59Z",
1417 "2099-12-31T23:59:59-01:00",
1418 "1980-01-01T00:15:35+01:00",
1419 "1980-01-01T10:15:35+14:00"
1420 })
1421 void testThrownParseOutputTimestampInvalidRange(String outputTimestamp) {
1422
1423 assertThatExceptionOfType(IllegalArgumentException.class)
1424 .isThrownBy(() -> MavenArchiver.parseBuildOutputTimestamp(outputTimestamp))
1425 .withMessageContaining("is not within the valid range 1980-01-01T00:00:02Z to 2099-12-31T23:59:59Z");
1426 }
1427
1428 @ParameterizedTest
1429 @CsvSource({
1430 "2011-12-03T10:15:30+01,1322903730",
1431 "2019-10-05T20:37:42+02,1570300662",
1432 "2011-12-03T10:15:30+06,1322885730",
1433 "1988-02-22T20:37:42+06,572539062"
1434 })
1435 @EnabledForJreRange(min = JRE.JAVA_9)
1436 void testShortOffset(String value, long expected) {
1437 assertThat(MavenArchiver.parseBuildOutputTimestamp(value)).contains(Instant.ofEpochSecond(expected));
1438 }
1439 }