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


Reply via email to