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