|
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