Author: bimargulies Date: Mon Jul 13 02:07:43 2015 New Revision: 1690562 URL: http://svn.apache.org/r1690562 Log: MSHADE-190: Shade does not relocate the contents of META-INF/services files o enhance ServicesResourceTransformer to include relocation.
Added: maven/plugins/trunk/maven-shade-plugin/src/test/java/org/apache/maven/plugins/shade/resource/ServiceResourceTransformerTest.java (with props) Modified: maven/plugins/trunk/maven-shade-plugin/src/main/java/org/apache/maven/plugins/shade/resource/ServicesResourceTransformer.java maven/plugins/trunk/maven-shade-plugin/src/site/apt/examples/resource-transformers.apt.vm Modified: maven/plugins/trunk/maven-shade-plugin/src/main/java/org/apache/maven/plugins/shade/resource/ServicesResourceTransformer.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-shade-plugin/src/main/java/org/apache/maven/plugins/shade/resource/ServicesResourceTransformer.java?rev=1690562&r1=1690561&r2=1690562&view=diff ============================================================================== --- maven/plugins/trunk/maven-shade-plugin/src/main/java/org/apache/maven/plugins/shade/resource/ServicesResourceTransformer.java (original) +++ maven/plugins/trunk/maven-shade-plugin/src/main/java/org/apache/maven/plugins/shade/resource/ServicesResourceTransformer.java Mon Jul 13 02:07:43 2015 @@ -19,6 +19,9 @@ package org.apache.maven.plugins.shade.r * under the License. */ +import com.google.common.base.Charsets; +import com.google.common.io.LineReader; +import org.apache.commons.io.IOUtils; import org.apache.maven.plugins.shade.relocation.Relocator; import org.codehaus.plexus.util.IOUtil; @@ -26,6 +29,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.StringReader; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -33,13 +37,11 @@ import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; /** - * Resources transformer that appends entries in META-INF/services resources into + * Resources transformer that relocates classes in META-INF/services and appends entries in META-INF/services resources into * a single resource. For example, if there are several META-INF/services/org.apache.maven.project.ProjectBuilder * resources spread across many JARs the individual entries will all be concatenated into a single * META-INF/services/org.apache.maven.project.ProjectBuilder resource packaged into the resultant JAR produced * by the shading process. - * - * @author jvanzyl */ public class ServicesResourceTransformer implements ResourceTransformer @@ -59,7 +61,7 @@ public class ServicesResourceTransformer return false; } - public void processResource( String resource, InputStream is, List<Relocator> relocators ) + public void processResource( String resource, InputStream is, final List<Relocator> relocators ) throws IOException { ServiceStream out = serviceEntries.get( resource ); @@ -69,10 +71,24 @@ public class ServicesResourceTransformer serviceEntries.put( resource, out ); } - out.append( is ); + final ServiceStream fout = out; + + final String content = IOUtils.toString( is ); + StringReader reader = new StringReader( content ); + LineReader lineReader = new LineReader( reader ); + String line; + while ( ( line = lineReader.readLine() ) != null ) + { + String relContent = line; + for ( Relocator relocator : relocators ) + { + relContent = relocator.applyToSourceContent( relContent ); + } + fout.append( relContent + "\n" ); + } + is.close(); } - public boolean hasTransformedResource() { return serviceEntries.size() > 0; @@ -101,7 +117,7 @@ public class ServicesResourceTransformer super( 1024 ); } - public void append( InputStream is ) + public void append( String content ) throws IOException { if ( count > 0 && buf[count - 1] != '\n' && buf[count - 1] != '\r' ) @@ -109,7 +125,8 @@ public class ServicesResourceTransformer write( '\n' ); } - IOUtil.copy( is, this ); + byte[] contentBytes = content.getBytes( Charsets.UTF_8 ); + this.write( contentBytes ); } public InputStream toInputStream() Modified: maven/plugins/trunk/maven-shade-plugin/src/site/apt/examples/resource-transformers.apt.vm URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-shade-plugin/src/site/apt/examples/resource-transformers.apt.vm?rev=1690562&r1=1690561&r2=1690562&view=diff ============================================================================== --- maven/plugins/trunk/maven-shade-plugin/src/site/apt/examples/resource-transformers.apt.vm (original) +++ maven/plugins/trunk/maven-shade-plugin/src/site/apt/examples/resource-transformers.apt.vm Mon Jul 13 02:07:43 2015 @@ -47,7 +47,7 @@ Resource Transformers *-----------------------------------------+------------------------------------------+ | {{PluginXmlResourceTransformer}} | Aggregates Mavens <<<plugin.xml>>> | *-----------------------------------------+------------------------------------------+ -| {{ServicesResourceTransformer}} | Merges <<<META-INF/services>>> resources | +| {{ServicesResourceTransformer}} | Relocated class names in <<<META-INF/services>>> resources and merges them. | *-----------------------------------------+------------------------------------------+ | {{XmlAppendingTransformer}} | Adds XML content to an XML resource | *-----------------------------------------+------------------------------------------+ @@ -129,7 +129,9 @@ Transformers in <<<org.apache.maven.plug * Concatenating Service Entries with the {ServicesResourceTransformer} JAR files providing implementations of some interfaces often ship with a <<<META-INF/services/>>> directory that - maps interfaces to their implementation classes for lookup by the service locator. To merge multiple implementations + maps interfaces to their implementation classes for lookup by the service locator. + To relocate the class names of these implementation classes, and to + To merge multiple implementations of the same interface into one service entry, the <<<ServicesResourceTransformer>>> can be used: +----- Added: maven/plugins/trunk/maven-shade-plugin/src/test/java/org/apache/maven/plugins/shade/resource/ServiceResourceTransformerTest.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-shade-plugin/src/test/java/org/apache/maven/plugins/shade/resource/ServiceResourceTransformerTest.java?rev=1690562&view=auto ============================================================================== --- maven/plugins/trunk/maven-shade-plugin/src/test/java/org/apache/maven/plugins/shade/resource/ServiceResourceTransformerTest.java (added) +++ maven/plugins/trunk/maven-shade-plugin/src/test/java/org/apache/maven/plugins/shade/resource/ServiceResourceTransformerTest.java Mon Jul 13 02:07:43 2015 @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.maven.plugins.shade.resource; + +import com.google.common.base.Charsets; +import com.google.common.collect.Lists; +import org.apache.commons.io.IOUtils; +import org.apache.maven.plugins.shade.relocation.Relocator; +import org.apache.maven.plugins.shade.relocation.SimpleRelocator; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * Test for handling META-INF/service/... + */ +public class ServiceResourceTransformerTest { + + @Test + public void relocatedClasses() throws Exception { + SimpleRelocator relocator = new SimpleRelocator("org.foo", "borg.foo", null, null); + List<Relocator> relocators = Lists.<Relocator>newArrayList( relocator ); + + String content = "org.foo.Service\n"; + byte[] contentBytes = content.getBytes( Charsets.UTF_8 ); + InputStream contentStream = new ByteArrayInputStream( contentBytes ); + String contentResource = "META-INF/services/org.something.another"; + + ServicesResourceTransformer xformer = new ServicesResourceTransformer(); + xformer.processResource( contentResource, contentStream, relocators ); + + File tempJar = File.createTempFile("shade.", ".jar"); + tempJar.deleteOnExit(); + FileOutputStream fos = new FileOutputStream( tempJar ); + JarOutputStream jos = new JarOutputStream( fos ); + try { + xformer.modifyOutputStream( jos ); + jos.close(); + jos = null; + JarFile jarFile = new JarFile( tempJar ); + JarEntry jarEntry = jarFile.getJarEntry( contentResource ); + assertNotNull( jarEntry ); + InputStream entryStream = jarFile.getInputStream( jarEntry ); + try { + String xformedContent = IOUtils.toString(entryStream, "utf-8"); + assertEquals("borg.foo.Service\n", xformedContent); + } finally { + IOUtils.closeQuietly( entryStream ); + } + } finally { + if (jos != null) + { + IOUtils.closeQuietly( jos ); + } + tempJar.delete(); + } + } + + @Test + public void concatenation() throws Exception { + SimpleRelocator relocator = new SimpleRelocator("org.foo", "borg.foo", null, null); + List<Relocator> relocators = Lists.<Relocator>newArrayList( relocator ); + + String content = "org.foo.Service\n"; + byte[] contentBytes = content.getBytes( Charsets.UTF_8 ); + InputStream contentStream = new ByteArrayInputStream( contentBytes ); + String contentResource = "META-INF/services/org.something.another"; + + ServicesResourceTransformer xformer = new ServicesResourceTransformer(); + xformer.processResource( contentResource, contentStream, relocators ); + + content = "org.blah.Service\n"; + contentBytes = content.getBytes( Charsets.UTF_8 ); + contentStream = new ByteArrayInputStream( contentBytes ); + contentResource = "META-INF/services/org.something.another"; + + xformer.processResource( contentResource, contentStream, relocators ); + + File tempJar = File.createTempFile("shade.", ".jar"); + tempJar.deleteOnExit(); + FileOutputStream fos = new FileOutputStream( tempJar ); + JarOutputStream jos = new JarOutputStream( fos ); + try { + xformer.modifyOutputStream( jos ); + jos.close(); + jos = null; + JarFile jarFile = new JarFile( tempJar ); + JarEntry jarEntry = jarFile.getJarEntry( contentResource ); + assertNotNull( jarEntry ); + InputStream entryStream = jarFile.getInputStream( jarEntry ); + try { + String xformedContent = IOUtils.toString(entryStream, "utf-8"); + // must be two lines, with our two classes. + String[] classes = xformedContent.split("\n"); + boolean h1 = false; + boolean h2 = false; + for ( String name : classes ) + { + if ("org.blah.Service".equals( name )) + { + h1 = true; + } + else if ("borg.foo.Service".equals( name )) + { + h2 = true; + } + } + assertTrue( h1 && h2 ); + } finally { + IOUtils.closeQuietly( entryStream ); + } + } finally { + if (jos != null) + { + IOUtils.closeQuietly( jos ); + } + tempJar.delete(); + } + } +} Propchange: maven/plugins/trunk/maven-shade-plugin/src/test/java/org/apache/maven/plugins/shade/resource/ServiceResourceTransformerTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/plugins/trunk/maven-shade-plugin/src/test/java/org/apache/maven/plugins/shade/resource/ServiceResourceTransformerTest.java ------------------------------------------------------------------------------ svn:mime-type = text/plain