Skip to content

Commit e342059

Browse files
authored
[MSHADE-432] Duplicate services entries can be generated (#159)
1 parent 7603e57 commit e342059

File tree

3 files changed

+61
-6
lines changed

3 files changed

+61
-6
lines changed

src/main/java/org/apache/maven/plugins/shade/resource/ServicesResourceTransformer.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@
2222
import java.io.IOException;
2323
import java.io.InputStream;
2424
import java.nio.charset.StandardCharsets;
25-
import java.util.ArrayList;
2625
import java.util.HashMap;
26+
import java.util.LinkedHashSet;
2727
import java.util.List;
2828
import java.util.Map;
2929
import java.util.Scanner;
30+
import java.util.Set;
3031
import java.util.jar.JarEntry;
3132
import java.util.jar.JarOutputStream;
3233

@@ -45,7 +46,7 @@ public class ServicesResourceTransformer
4546
{
4647
private static final String SERVICES_PATH = "META-INF/services";
4748

48-
private final Map<String, ArrayList<String>> serviceEntries = new HashMap<>();
49+
private final Map<String, Set<String>> serviceEntries = new HashMap<>();
4950

5051
private long time = Long.MIN_VALUE;
5152

@@ -68,7 +69,7 @@ public void processResource( String resource, InputStream is, final List<Relocat
6869
}
6970
resource = SERVICES_PATH + '/' + resource;
7071

71-
ArrayList<String> out = serviceEntries.computeIfAbsent( resource, k -> new ArrayList<>() );
72+
Set<String> out = serviceEntries.computeIfAbsent( resource, k -> new LinkedHashSet<>() );
7273

7374
Scanner scanner = new Scanner( is, StandardCharsets.UTF_8.name() );
7475
while ( scanner.hasNextLine() )
@@ -98,10 +99,10 @@ public boolean hasTransformedResource()
9899
public void modifyOutputStream( JarOutputStream jos )
99100
throws IOException
100101
{
101-
for ( Map.Entry<String, ArrayList<String>> entry : serviceEntries.entrySet() )
102+
for ( Map.Entry<String, Set<String>> entry : serviceEntries.entrySet() )
102103
{
103104
String key = entry.getKey();
104-
ArrayList<String> data = entry.getValue();
105+
Set<String> data = entry.getValue();
105106

106107
JarEntry jarEntry = new JarEntry( key );
107108
jarEntry.setTime( time );

src/test/java/org/apache/maven/plugins/shade/DefaultShaderTest.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919
* under the License.
2020
*/
2121

22+
import java.io.BufferedReader;
2223
import java.io.File;
2324
import java.io.FileInputStream;
2425
import java.io.FileOutputStream;
2526
import java.io.IOException;
2627
import java.io.InputStream;
28+
import java.io.InputStreamReader;
2729
import java.lang.reflect.Field;
2830
import java.net.URL;
2931
import java.net.URLClassLoader;
@@ -40,6 +42,7 @@
4042
import java.util.jar.JarEntry;
4143
import java.util.jar.JarFile;
4244
import java.util.jar.JarOutputStream;
45+
import java.util.stream.Collectors;
4346
import java.util.zip.CRC32;
4447
import java.util.zip.ZipEntry;
4548

@@ -50,6 +53,7 @@
5053
import org.apache.maven.plugins.shade.resource.AppendingTransformer;
5154
import org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer;
5255
import org.apache.maven.plugins.shade.resource.ResourceTransformer;
56+
import org.apache.maven.plugins.shade.resource.ServicesResourceTransformer;
5357
import org.codehaus.plexus.util.IOUtil;
5458
import org.codehaus.plexus.util.Os;
5559
import org.junit.Assert;
@@ -83,6 +87,8 @@ public class DefaultShaderTest
8387
private static final String[] EXCLUDES = new String[] { "org/codehaus/plexus/util/xml/Xpp3Dom",
8488
"org/codehaus/plexus/util/xml/pull.*" };
8589

90+
private final String NEWLINE = "\n";
91+
8692
@Test
8793
public void testNoopWhenNotRelocated() throws IOException, MojoExecutionException {
8894
final File plexusJar = new File("src/test/jars/plexus-utils-1.4.1.jar" );
@@ -423,6 +429,54 @@ public void testShaderNoOverwrite() throws Exception
423429
temporaryFolder.delete();
424430
}
425431

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+
426480
private void writeEntryWithoutCompression( String entryName, byte[] entryBytes, JarOutputStream jos ) throws IOException
427481
{
428482
final JarEntry entry = new JarEntry( entryName );

src/test/java/org/apache/maven/plugins/shade/resource/ServiceResourceTransformerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public void mergeRelocatedFiles() throws Exception {
121121
assertNotNull( jarEntry );
122122
try ( InputStream entryStream = jarFile.getInputStream( jarEntry ) ) {
123123
String xformedContent = IOUtils.toString( entryStream, StandardCharsets.UTF_8);
124-
assertEquals( contentShaded + contentShaded, xformedContent );
124+
assertEquals( contentShaded, xformedContent );
125125
} finally {
126126
jarFile.close();
127127
}

0 commit comments

Comments
 (0)