1 package org.apache.maven.plugins.shade.mojo;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import static java.util.Arrays.asList;
23 import static java.util.Collections.singletonList;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.when;
26
27 import java.io.File;
28 import java.lang.reflect.Field;
29 import java.lang.reflect.Method;
30 import java.net.URL;
31 import java.net.URLClassLoader;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.LinkedHashSet;
35 import java.util.List;
36 import java.util.Set;
37
38 import org.apache.maven.artifact.Artifact;
39 import org.apache.maven.artifact.DefaultArtifact;
40 import org.apache.maven.artifact.handler.ArtifactHandler;
41 import org.apache.maven.artifact.versioning.VersionRange;
42 import org.apache.maven.execution.MavenSession;
43 import org.apache.maven.plugins.shade.ShadeRequest;
44 import org.apache.maven.plugins.shade.Shader;
45 import org.apache.maven.plugins.shade.filter.Filter;
46 import org.apache.maven.plugins.shade.relocation.Relocator;
47 import org.apache.maven.plugins.shade.relocation.SimpleRelocator;
48 import org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer;
49 import org.apache.maven.plugins.shade.resource.ManifestResourceTransformer;
50 import org.apache.maven.plugins.shade.resource.ResourceTransformer;
51 import org.apache.maven.project.MavenProject;
52 import org.apache.maven.project.ProjectBuildingRequest;
53 import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate;
54 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver;
55 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
56 import org.codehaus.plexus.ContainerConfiguration;
57 import org.codehaus.plexus.PlexusConstants;
58 import org.codehaus.plexus.PlexusTestCase;
59
60
61
62
63
64 public class ShadeMojoTest
65 extends PlexusTestCase
66 {
67 @Override
68 protected void customizeContainerConfiguration(final ContainerConfiguration configuration) {
69 configuration.setClassPathScanning(PlexusConstants.SCANNING_INDEX);
70 }
71
72 public void testManifestTransformerSelection() throws Exception
73 {
74 final ShadeMojo mojo = new ShadeMojo();
75 final Method m = ShadeMojo.class.getDeclaredMethod("toResourceTransformers", String.class, List.class);
76 m.setAccessible(true);
77
78 final ManifestResourceTransformer defaultTfr = new ManifestResourceTransformer()
79 {
80 @Override
81 public String toString()
82 {
83 return "default";
84 }
85 };
86 final ManifestResourceTransformer testsTfr1 = new ManifestResourceTransformer()
87 {
88 @Override
89 public String toString()
90 {
91 return "t1";
92 }
93 };
94 testsTfr1.setForShade("tests");
95 final ManifestResourceTransformer testsTfr2 = new ManifestResourceTransformer()
96 {
97 @Override
98 public String toString()
99 {
100 return "t2";
101 }
102 };
103 testsTfr2.setForShade("tests");
104
105 assertEquals(
106 singletonList( defaultTfr ),
107 m.invoke( mojo, "jar", asList( defaultTfr, testsTfr1, testsTfr2 ) ));
108 assertEquals(
109 asList( testsTfr1, testsTfr2 ),
110 m.invoke( mojo, "tests", asList( defaultTfr, testsTfr1, testsTfr2 ) ));
111 assertEquals(
112 asList( testsTfr1, testsTfr2 ),
113 m.invoke( mojo, "tests", asList( testsTfr1, defaultTfr, testsTfr2 ) ));
114 assertEquals(
115 asList( testsTfr1, testsTfr2 ),
116 m.invoke( mojo, "tests", asList( testsTfr1, testsTfr2, defaultTfr ) ));
117 }
118
119 public void testShaderWithDefaultShadedPattern()
120 throws Exception
121 {
122 shaderWithPattern( null, new File( "target/foo-default.jar" ) );
123 }
124
125 public void testShaderWithCustomShadedPattern()
126 throws Exception
127 {
128 shaderWithPattern( "org/shaded/plexus/util", new File( "target/foo-custom.jar" ) );
129 }
130
131 public void testShaderWithExclusions()
132 throws Exception
133 {
134 File jarFile = new File( getBasedir(), "target/unit/foo-bar.jar" );
135
136 Shader s = lookup( Shader.class );
137
138 Set<File> set = new LinkedHashSet<>();
139 set.add( new File( getBasedir(), "src/test/jars/test-artifact-1.0-SNAPSHOT.jar" ) );
140
141 List<Relocator> relocators = new ArrayList<>();
142 relocators.add( new SimpleRelocator( "org.codehaus.plexus.util", "hidden", null, Arrays.asList(
143 "org.codehaus.plexus.util.xml.Xpp3Dom", "org.codehaus.plexus.util.xml.pull.*") ) );
144
145 List<ResourceTransformer> resourceTransformers = new ArrayList<>();
146
147 List<Filter> filters = new ArrayList<>();
148
149 ShadeRequest shadeRequest = new ShadeRequest();
150 shadeRequest.setJars( set );
151 shadeRequest.setUberJar( jarFile );
152 shadeRequest.setFilters( filters );
153 shadeRequest.setRelocators( relocators );
154 shadeRequest.setResourceTransformers( resourceTransformers );
155
156 s.shade( shadeRequest );
157
158 try ( URLClassLoader cl = new URLClassLoader( new URL[]{ jarFile.toURI().toURL() } ) ) {
159 Class<?> c = cl.loadClass( "org.apache.maven.plugins.shade.Lib" );
160
161 Field field = c.getDeclaredField( "CLASS_REALM_PACKAGE_IMPORT" );
162 assertEquals( "org.codehaus.plexus.util.xml.pull", field.get( null ) );
163
164 Method method = c.getDeclaredMethod( "getClassRealmPackageImport" );
165 assertEquals( "org.codehaus.plexus.util.xml.pull", method.invoke( null ) );
166 }
167 }
168
169
170
171
172
173
174 public void testShadeWithFilter()
175 throws Exception
176 {
177 ShadeMojo mojo = new ShadeMojo();
178
179
180 Field createSourcesJar = ShadeMojo.class.getDeclaredField( "createSourcesJar" );
181 createSourcesJar.setAccessible( true );
182 createSourcesJar.set( mojo, Boolean.TRUE );
183
184
185 ArtifactResolver mockArtifactResolver = new ArtifactResolver()
186 {
187 @Override
188 public ArtifactResult resolveArtifact( ProjectBuildingRequest req, final Artifact art )
189 {
190 return new ArtifactResult()
191 {
192
193 @Override
194 public Artifact getArtifact()
195 {
196 art.setResolved( true );
197 String fileName = art.getArtifactId() + "-" + art.getVersion()
198 + ( art.getClassifier() != null ? "-" + art.getClassifier() : "" ) + ".jar";
199 art.setFile( new File( fileName ) );
200 return art;
201 }
202 };
203 }
204
205 @Override
206 public ArtifactResult resolveArtifact( ProjectBuildingRequest req, final ArtifactCoordinate coordinate )
207 {
208 return new ArtifactResult()
209 {
210
211 @Override
212 public Artifact getArtifact()
213 {
214 Artifact art = mock( Artifact.class );
215 when( art.getGroupId() ).thenReturn( coordinate.getGroupId() );
216 when( art.getArtifactId() ).thenReturn( coordinate.getArtifactId() );
217 when( art.getType() ).thenReturn( coordinate.getExtension() );
218 when( art.getClassifier() ).thenReturn( coordinate.getClassifier() );
219 when( art.isResolved() ).thenReturn( true );
220 String fileName = coordinate.getArtifactId() + "-" + coordinate.getVersion()
221 + ( coordinate.getClassifier() != null ? "-" + coordinate.getClassifier() : "" ) + ".jar";
222 when( art.getFile() ).thenReturn( new File( fileName ) );
223 return art;
224 }
225 };
226 }
227 };
228 Field artifactResolverField = ShadeMojo.class.getDeclaredField( "artifactResolver" );
229 artifactResolverField.setAccessible( true );
230 artifactResolverField.set( mojo, mockArtifactResolver );
231
232
233 MavenProject project = new MavenProject();
234 ArtifactHandler artifactHandler = lookup( ArtifactHandler.class );
235 Artifact artifact = new DefaultArtifact( "org.apache.myfaces.core", "myfaces-impl",
236 VersionRange.createFromVersion( "2.0.1-SNAPSHOT" ), "compile", "jar",
237 null, artifactHandler );
238 artifact = mockArtifactResolver.resolveArtifact( null, artifact ).getArtifact();
239 project.setArtifact( artifact );
240 Field projectField = ShadeMojo.class.getDeclaredField( "project" );
241 projectField.setAccessible( true );
242 projectField.set( mojo, project );
243
244
245 ArchiveFilter archiveFilter = new ArchiveFilter();
246 Field archiveFilterArtifact = ArchiveFilter.class.getDeclaredField( "artifact" );
247 archiveFilterArtifact.setAccessible( true );
248 archiveFilterArtifact.set( archiveFilter, "org.apache.myfaces.core:myfaces-impl" );
249
250
251 Field filtersField = ShadeMojo.class.getDeclaredField( "filters" );
252 filtersField.setAccessible( true );
253 filtersField.set( mojo, new ArchiveFilter[]{ archiveFilter } );
254
255 Field sessionField = ShadeMojo.class.getDeclaredField( "session" );
256 sessionField.setAccessible( true );
257 sessionField.set( mojo, mock( MavenSession.class ) );
258
259
260 Method getFilters = ShadeMojo.class.getDeclaredMethod( "getFilters" );
261 getFilters.setAccessible( true );
262 List<Filter> filters = (List<Filter>) getFilters.invoke( mojo);
263
264
265 assertEquals( 1, filters.size() );
266
267
268 Filter filter = filters.get( 0 );
269 assertTrue( filter.canFilter( new File( "myfaces-impl-2.0.1-SNAPSHOT.jar" ) ) );
270 assertTrue( filter.canFilter( new File( "myfaces-impl-2.0.1-SNAPSHOT-sources.jar" ) ) );
271 }
272
273 public void shaderWithPattern( String shadedPattern, File jar )
274 throws Exception
275 {
276 Shader s = lookup( Shader.class );
277
278 Set<File> set = new LinkedHashSet<>();
279
280 set.add( new File( getBasedir(), "src/test/jars/test-project-1.0-SNAPSHOT.jar" ) );
281
282 set.add( new File( getBasedir(), "src/test/jars/plexus-utils-1.4.1.jar" ) );
283
284 List<Relocator> relocators = new ArrayList<>();
285
286 relocators.add( new SimpleRelocator( "org/codehaus/plexus/util", shadedPattern, null, Arrays.asList(
287 "org/codehaus/plexus/util/xml/Xpp3Dom", "org/codehaus/plexus/util/xml/pull.*") ) );
288
289 List<ResourceTransformer> resourceTransformers = new ArrayList<>();
290
291 resourceTransformers.add( new ComponentsXmlResourceTransformer() );
292
293 List<Filter> filters = new ArrayList<>();
294
295 ShadeRequest shadeRequest = new ShadeRequest();
296 shadeRequest.setJars( set );
297 shadeRequest.setUberJar( jar );
298 shadeRequest.setFilters( filters );
299 shadeRequest.setRelocators( relocators );
300 shadeRequest.setResourceTransformers( resourceTransformers );
301
302 s.shade( shadeRequest );
303 }
304
305 }