1 package org.apache.maven.plugins.shade;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.net.URL;
25 import java.net.URLClassLoader;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Collections;
29 import java.util.LinkedHashSet;
30 import java.util.List;
31 import java.util.Set;
32
33 import junit.framework.TestCase;
34
35 import org.apache.maven.plugin.MojoExecutionException;
36 import org.apache.maven.plugins.shade.filter.Filter;
37 import org.apache.maven.plugins.shade.relocation.Relocator;
38 import org.apache.maven.plugins.shade.relocation.SimpleRelocator;
39 import org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer;
40 import org.apache.maven.plugins.shade.resource.ResourceTransformer;
41 import org.codehaus.plexus.logging.AbstractLogger;
42 import org.codehaus.plexus.logging.Logger;
43 import org.codehaus.plexus.logging.console.ConsoleLogger;
44 import org.objectweb.asm.ClassReader;
45 import org.objectweb.asm.ClassVisitor;
46 import org.objectweb.asm.Opcodes;
47
48
49
50
51
52 public class DefaultShaderTest
53 extends TestCase
54 {
55 private static final String[] EXCLUDES = new String[] { "org/codehaus/plexus/util/xml/Xpp3Dom",
56 "org/codehaus/plexus/util/xml/pull.*" };
57
58 public void testOverlappingResourcesAreLogged() throws IOException, MojoExecutionException {
59 final DefaultShader shader = new DefaultShader();
60 final List<String> debugMessages = new ArrayList<>();
61 final List<String> warnMessages = new ArrayList<>();
62 shader.enableLogging( new AbstractLogger(
63 Logger.LEVEL_INFO, "TEST_DefaultShaderTest_testOverlappingResourcesAreLogged" )
64 {
65 @Override
66 public void debug( final String s, final Throwable throwable )
67 {
68 debugMessages.add( s.replace( '\\', '/' ).trim() );
69 }
70
71 @Override
72 public void info( final String s, final Throwable throwable )
73 {
74
75 }
76
77 @Override
78 public void warn( final String s, final Throwable throwable )
79 {
80 warnMessages.add( s.replace( '\\', '/' ).trim() );
81 }
82
83 @Override
84 public void error( final String s, final Throwable throwable )
85 {
86
87 }
88
89 @Override
90 public void fatalError( final String s, final Throwable throwable )
91 {
92
93 }
94
95 @Override
96 public Logger getChildLogger( final String s )
97 {
98 return this;
99 }
100 });
101
102
103
104 final Set<File> set = new LinkedHashSet<>();
105 set.add( new File( "src/test/jars/test-project-1.0-SNAPSHOT.jar" ) );
106 set.add( new File( "src/test/jars/plexus-utils-1.4.1.jar" ) );
107
108 final ShadeRequest shadeRequest = new ShadeRequest();
109 shadeRequest.setJars( set );
110 shadeRequest.setRelocators( Collections.<Relocator>emptyList() );
111 shadeRequest.setResourceTransformers( Collections.<ResourceTransformer>emptyList() );
112 shadeRequest.setFilters( Collections.<Filter>emptyList() );
113 shadeRequest.setUberJar( new File( "target/foo-custom_testOverlappingResourcesAreLogged.jar" ) );
114 shader.shade( shadeRequest );
115
116 final String failureWarnMessage = warnMessages.toString();
117 assertTrue(failureWarnMessage, warnMessages.contains(
118 "plexus-utils-1.4.1.jar, test-project-1.0-SNAPSHOT.jar define 1 overlapping resources:"));
119 assertTrue(failureWarnMessage, warnMessages.contains("- META-INF/MANIFEST.MF"));
120
121 final String failureDebugMessage = debugMessages.toString();
122 assertTrue(failureDebugMessage, debugMessages.contains(
123 "We have a duplicate META-INF/MANIFEST.MF in src/test/jars/plexus-utils-1.4.1.jar" ));
124 }
125
126 public void testShaderWithDefaultShadedPattern()
127 throws Exception
128 {
129 shaderWithPattern( null, new File( "target/foo-default.jar" ), EXCLUDES );
130 }
131
132 public void testShaderWithStaticInitializedClass()
133 throws Exception
134 {
135 Shader s = newShader();
136
137 Set<File> set = new LinkedHashSet<>();
138
139 set.add( new File( "src/test/jars/test-artifact-1.0-SNAPSHOT.jar" ) );
140
141 List<Relocator> relocators = new ArrayList<>();
142
143 relocators.add( new SimpleRelocator( "org.apache.maven.plugins.shade", null, null, null ) );
144
145 List<ResourceTransformer> resourceTransformers = new ArrayList<>();
146
147 List<Filter> filters = new ArrayList<>();
148
149 File file = new File( "target/testShaderWithStaticInitializedClass.jar" );
150
151 ShadeRequest shadeRequest = new ShadeRequest();
152 shadeRequest.setJars( set );
153 shadeRequest.setUberJar( file );
154 shadeRequest.setFilters( filters );
155 shadeRequest.setRelocators( relocators );
156 shadeRequest.setResourceTransformers( resourceTransformers );
157
158 s.shade( shadeRequest );
159
160 URLClassLoader cl = new URLClassLoader( new URL[] { file.toURI().toURL() } );
161 Class<?> c = cl.loadClass( "hidden.org.apache.maven.plugins.shade.Lib" );
162 Object o = c.newInstance();
163 assertEquals( "foo.bar/baz", c.getDeclaredField( "CONSTANT" ).get( o ) );
164 }
165
166 public void testShaderWithCustomShadedPattern()
167 throws Exception
168 {
169 shaderWithPattern( "org/shaded/plexus/util", new File( "target/foo-custom.jar" ), EXCLUDES );
170 }
171
172 public void testShaderWithoutExcludesShouldRemoveReferencesOfOriginalPattern()
173 throws Exception
174 {
175
176
177 shaderWithPattern( "org/shaded/plexus/util", new File( "target/foo-custom-without-excludes.jar" ),
178 new String[] {} );
179 }
180
181 public void testShaderWithRelocatedClassname()
182 throws Exception
183 {
184 DefaultShader s = newShader();
185
186 Set<File> set = new LinkedHashSet<>();
187
188 set.add( new File( "src/test/jars/test-project-1.0-SNAPSHOT.jar" ) );
189
190 set.add( new File( "src/test/jars/plexus-utils-1.4.1.jar" ) );
191
192 List<Relocator> relocators = new ArrayList<>();
193
194 relocators.add( new SimpleRelocator( "org/codehaus/plexus/util/", "_plexus/util/__", null,
195 Arrays.<String> asList() ) );
196
197 List<ResourceTransformer> resourceTransformers = new ArrayList<>();
198
199 resourceTransformers.add( new ComponentsXmlResourceTransformer() );
200
201 List<Filter> filters = new ArrayList<>();
202
203 File file = new File( "target/foo-relocate-class.jar" );
204
205 ShadeRequest shadeRequest = new ShadeRequest();
206 shadeRequest.setJars( set );
207 shadeRequest.setUberJar( file );
208 shadeRequest.setFilters( filters );
209 shadeRequest.setRelocators( relocators );
210 shadeRequest.setResourceTransformers( resourceTransformers );
211
212 s.shade( shadeRequest );
213
214 URLClassLoader cl = new URLClassLoader( new URL[] { file.toURI().toURL() } );
215 Class<?> c = cl.loadClass( "_plexus.util.__StringUtils" );
216
217 Object o = c.newInstance();
218 assertEquals( "", c.getMethod( "clean", String.class ).invoke( o, (String) null ) );
219
220
221 final String[] source = { null };
222 final ClassReader classReader = new ClassReader( cl.getResourceAsStream( "_plexus/util/__StringUtils.class" ) );
223 classReader.accept( new ClassVisitor( Opcodes.ASM4 )
224 {
225 @Override
226 public void visitSource( String arg0, String arg1 )
227 {
228 super.visitSource( arg0, arg1 );
229 source[0] = arg0;
230 }
231 }, ClassReader.SKIP_CODE );
232 assertEquals( "__StringUtils.java", source[0] );
233 }
234
235 private void shaderWithPattern( String shadedPattern, File jar, String[] excludes )
236 throws Exception
237 {
238 DefaultShader s = newShader();
239
240 Set<File> set = new LinkedHashSet<>();
241
242 set.add( new File( "src/test/jars/test-project-1.0-SNAPSHOT.jar" ) );
243
244 set.add( new File( "src/test/jars/plexus-utils-1.4.1.jar" ) );
245
246 List<Relocator> relocators = new ArrayList<>();
247
248 relocators.add( new SimpleRelocator( "org/codehaus/plexus/util", shadedPattern, null, Arrays.asList( excludes ) ) );
249
250 List<ResourceTransformer> resourceTransformers = new ArrayList<>();
251
252 resourceTransformers.add( new ComponentsXmlResourceTransformer() );
253
254 List<Filter> filters = new ArrayList<>();
255
256 ShadeRequest shadeRequest = new ShadeRequest();
257 shadeRequest.setJars( set );
258 shadeRequest.setUberJar( jar );
259 shadeRequest.setFilters( filters );
260 shadeRequest.setRelocators( relocators );
261 shadeRequest.setResourceTransformers( resourceTransformers );
262
263 s.shade( shadeRequest );
264 }
265
266 private static DefaultShader newShader()
267 {
268 DefaultShader s = new DefaultShader();
269
270 s.enableLogging( new ConsoleLogger( Logger.LEVEL_INFO, "TEST" ) );
271
272 return s;
273 }
274
275 }