|
19 | 19 | * under the License. |
20 | 20 | */ |
21 | 21 |
|
| 22 | +import java.io.BufferedReader; |
22 | 23 | import java.io.File; |
23 | 24 | import java.io.FileInputStream; |
24 | 25 | import java.io.FileOutputStream; |
25 | 26 | import java.io.IOException; |
26 | 27 | import java.io.InputStream; |
| 28 | +import java.io.InputStreamReader; |
27 | 29 | import java.lang.reflect.Field; |
28 | 30 | import java.net.URL; |
29 | 31 | import java.net.URLClassLoader; |
|
40 | 42 | import java.util.jar.JarEntry; |
41 | 43 | import java.util.jar.JarFile; |
42 | 44 | import java.util.jar.JarOutputStream; |
| 45 | +import java.util.stream.Collectors; |
43 | 46 | import java.util.zip.CRC32; |
44 | 47 | import java.util.zip.ZipEntry; |
45 | 48 |
|
|
50 | 53 | import org.apache.maven.plugins.shade.resource.AppendingTransformer; |
51 | 54 | import org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer; |
52 | 55 | import org.apache.maven.plugins.shade.resource.ResourceTransformer; |
| 56 | +import org.apache.maven.plugins.shade.resource.ServicesResourceTransformer; |
53 | 57 | import org.codehaus.plexus.util.IOUtil; |
54 | 58 | import org.codehaus.plexus.util.Os; |
55 | 59 | import org.junit.Assert; |
@@ -83,6 +87,8 @@ public class DefaultShaderTest |
83 | 87 | private static final String[] EXCLUDES = new String[] { "org/codehaus/plexus/util/xml/Xpp3Dom", |
84 | 88 | "org/codehaus/plexus/util/xml/pull.*" }; |
85 | 89 |
|
| 90 | + private final String NEWLINE = "\n"; |
| 91 | + |
86 | 92 | @Test |
87 | 93 | public void testNoopWhenNotRelocated() throws IOException, MojoExecutionException { |
88 | 94 | final File plexusJar = new File("src/test/jars/plexus-utils-1.4.1.jar" ); |
@@ -423,6 +429,54 @@ public void testShaderNoOverwrite() throws Exception |
423 | 429 | temporaryFolder.delete(); |
424 | 430 | } |
425 | 431 |
|
| 432 | + @Test |
| 433 | + public void testShaderWithDuplicateService() throws Exception |
| 434 | + { |
| 435 | + TemporaryFolder temporaryFolder = new TemporaryFolder(); |
| 436 | + temporaryFolder.create(); |
| 437 | + |
| 438 | + String serviceEntryName = "META-INF/services/my.foo.Service"; |
| 439 | + String serviceEntryValue = "my.foo.impl.Service1"; |
| 440 | + |
| 441 | + File innerJar1 = temporaryFolder.newFile( "inner1.jar" ); |
| 442 | + try (JarOutputStream jos = new JarOutputStream(Files.newOutputStream( innerJar1.toPath() ) ) ) |
| 443 | + { |
| 444 | + jos.putNextEntry( new JarEntry(serviceEntryName) ); |
| 445 | + jos.write( ( serviceEntryValue + NEWLINE ).getBytes( StandardCharsets.UTF_8 ) ); |
| 446 | + jos.closeEntry(); |
| 447 | + } |
| 448 | + |
| 449 | + File innerJar2 = temporaryFolder.newFile( "inner2.jar" ); |
| 450 | + try ( JarOutputStream jos = new JarOutputStream( Files.newOutputStream( innerJar2.toPath() ) ) ) |
| 451 | + { |
| 452 | + jos.putNextEntry( new JarEntry(serviceEntryName) ); |
| 453 | + jos.write( ( serviceEntryValue + NEWLINE ).getBytes( StandardCharsets.UTF_8 ) ); |
| 454 | + jos.closeEntry(); |
| 455 | + } |
| 456 | + |
| 457 | + ShadeRequest shadeRequest = new ShadeRequest(); |
| 458 | + shadeRequest.setJars( new LinkedHashSet<>( Arrays.asList( innerJar1, innerJar2 ) ) ); |
| 459 | + shadeRequest.setFilters( Collections.emptyList() ); |
| 460 | + shadeRequest.setRelocators( Collections.emptyList() ); |
| 461 | + shadeRequest.setResourceTransformers( Collections.singletonList( new ServicesResourceTransformer() ) ); |
| 462 | + File shadedFile = temporaryFolder.newFile( "shaded.jar" ); |
| 463 | + shadeRequest.setUberJar( shadedFile ); |
| 464 | + |
| 465 | + DefaultShader shader = newShader(); |
| 466 | + shader.shade( shadeRequest ); |
| 467 | + |
| 468 | + JarFile shadedJarFile = new JarFile( shadedFile ); |
| 469 | + JarEntry entry = shadedJarFile.getJarEntry(serviceEntryName); |
| 470 | + |
| 471 | + List<String> lines = new BufferedReader( new InputStreamReader( shadedJarFile.getInputStream( entry ), StandardCharsets.UTF_8 ) ) |
| 472 | + .lines().collect( Collectors.toList() ); |
| 473 | + |
| 474 | + //After shading, there should be a single input |
| 475 | + Assert.assertEquals( Collections.singletonList( serviceEntryValue ), lines ); |
| 476 | + |
| 477 | + temporaryFolder.delete(); |
| 478 | + } |
| 479 | + |
426 | 480 | private void writeEntryWithoutCompression( String entryName, byte[] entryBytes, JarOutputStream jos ) throws IOException |
427 | 481 | { |
428 | 482 | final JarEntry entry = new JarEntry( entryName ); |
|
0 commit comments