1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.shade.mojo;
20
21 import java.io.File;
22 import java.lang.reflect.Field;
23 import java.lang.reflect.Method;
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 org.apache.maven.artifact.Artifact;
34 import org.apache.maven.artifact.DefaultArtifact;
35 import org.apache.maven.artifact.handler.ArtifactHandler;
36 import org.apache.maven.artifact.versioning.VersionRange;
37 import org.apache.maven.execution.MavenExecutionRequest;
38 import org.apache.maven.execution.MavenExecutionResult;
39 import org.apache.maven.execution.MavenSession;
40 import org.apache.maven.plugin.testing.AbstractMojoTestCase;
41 import org.apache.maven.plugins.shade.ShadeRequest;
42 import org.apache.maven.plugins.shade.Shader;
43 import org.apache.maven.plugins.shade.filter.Filter;
44 import org.apache.maven.plugins.shade.relocation.Relocator;
45 import org.apache.maven.plugins.shade.relocation.SimpleRelocator;
46 import org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer;
47 import org.apache.maven.plugins.shade.resource.ManifestResourceTransformer;
48 import org.apache.maven.plugins.shade.resource.ResourceTransformer;
49 import org.apache.maven.project.MavenProject;
50 import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
51 import org.codehaus.plexus.ContainerConfiguration;
52 import org.codehaus.plexus.PlexusConstants;
53 import org.eclipse.aether.DefaultRepositorySystemSession;
54 import org.eclipse.aether.RepositorySystem;
55 import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
56 import org.eclipse.aether.repository.LocalRepository;
57 import org.eclipse.aether.resolution.ArtifactRequest;
58 import org.eclipse.aether.resolution.ArtifactResult;
59
60 import static java.util.Arrays.asList;
61 import static java.util.Collections.singletonList;
62 import static org.mockito.ArgumentMatchers.any;
63 import static org.mockito.ArgumentMatchers.eq;
64 import static org.mockito.Mockito.mock;
65 import static org.mockito.Mockito.when;
66
67
68
69
70
71 public class ShadeMojoTest extends AbstractMojoTestCase {
72 @Override
73 protected void customizeContainerConfiguration(final ContainerConfiguration configuration) {
74 configuration.setClassPathScanning(PlexusConstants.SCANNING_INDEX);
75 }
76
77 public void testManifestTransformerSelection() throws Exception {
78 final ShadeMojo mojo = new ShadeMojo();
79 final Method m = ShadeMojo.class.getDeclaredMethod("toResourceTransformers", String.class, List.class);
80 m.setAccessible(true);
81
82 final ManifestResourceTransformer defaultTfr = new ManifestResourceTransformer() {
83 @Override
84 public String toString()
85 {
86 return "default";
87 }
88 };
89 final ManifestResourceTransformer testsTfr1 = new ManifestResourceTransformer() {
90 @Override
91 public String toString() {
92 return "t1";
93 }
94 };
95 testsTfr1.setForShade("tests");
96 final ManifestResourceTransformer testsTfr2 = new ManifestResourceTransformer() {
97 @Override
98 public String toString() {
99 return "t2";
100 }
101 };
102 testsTfr2.setForShade("tests");
103
104 assertEquals(singletonList(defaultTfr), m.invoke(mojo, "jar", asList(defaultTfr, testsTfr1, testsTfr2)));
105 assertEquals(asList(testsTfr1, testsTfr2), m.invoke(mojo, "tests", asList(defaultTfr, testsTfr1, testsTfr2)));
106 assertEquals(asList(testsTfr1, testsTfr2), m.invoke(mojo, "tests", asList(testsTfr1, defaultTfr, testsTfr2)));
107 assertEquals(asList(testsTfr1, testsTfr2), m.invoke(mojo, "tests", asList(testsTfr1, testsTfr2, defaultTfr)));
108 }
109
110 public void testShaderWithDefaultShadedPattern() throws Exception {
111 shaderWithPattern(null, new File("target/foo-default.jar"));
112 }
113
114 public void testShaderWithCustomShadedPattern() throws Exception {
115 shaderWithPattern("org/shaded/plexus/util", new File("target/foo-custom.jar"));
116 }
117
118 public void testShaderWithExclusions() throws Exception {
119 File jarFile = new File(getBasedir(), "target/unit/foo-bar.jar");
120
121 Shader s = lookup(Shader.class);
122
123 Set<File> set = new LinkedHashSet<>();
124 set.add(new File(getBasedir(), "src/test/jars/test-artifact-1.0-SNAPSHOT.jar"));
125
126 List<Relocator> relocators = new ArrayList<>();
127 relocators.add(new SimpleRelocator(
128 "org.codehaus.plexus.util",
129 "hidden",
130 null,
131 Arrays.asList("org.codehaus.plexus.util.xml.Xpp3Dom", "org.codehaus.plexus.util.xml.pull.*")));
132
133 List<ResourceTransformer> resourceTransformers = new ArrayList<>();
134
135 List<Filter> filters = new ArrayList<>();
136
137 ShadeRequest shadeRequest = new ShadeRequest();
138 shadeRequest.setJars(set);
139 shadeRequest.setUberJar(jarFile);
140 shadeRequest.setFilters(filters);
141 shadeRequest.setRelocators(relocators);
142 shadeRequest.setResourceTransformers(resourceTransformers);
143
144 s.shade(shadeRequest);
145
146 try (URLClassLoader cl = new URLClassLoader(new URL[] {jarFile.toURI().toURL()})) {
147 Class<?> c = cl.loadClass("org.apache.maven.plugins.shade.Lib");
148
149 Field field = c.getDeclaredField("CLASS_REALM_PACKAGE_IMPORT");
150 assertEquals("org.codehaus.plexus.util.xml.pull", field.get(null));
151
152 Method method = c.getDeclaredMethod("getClassRealmPackageImport");
153 assertEquals("org.codehaus.plexus.util.xml.pull", method.invoke(null));
154 }
155 }
156
157
158
159
160
161
162 public void testShadeWithFilter() throws Exception {
163
164 MavenProject project = new MavenProject();
165 ArtifactHandler artifactHandler = lookup(ArtifactHandler.class);
166 Artifact artifact = new DefaultArtifact(
167 "org.apache.myfaces.core",
168 "myfaces-impl",
169 VersionRange.createFromVersion("2.0.1-SNAPSHOT"),
170 "compile",
171 "jar",
172 null,
173 artifactHandler);
174 artifact.setFile(new File("myfaces-impl-2.0.1-SNAPSHOT.jar"));
175 project.setArtifact(artifact);
176
177 ShadeMojo mojo = (ShadeMojo) lookupConfiguredMojo(project, "shade");
178
179 DefaultRepositorySystemSession repositorySystemSession = MavenRepositorySystemUtils.newSession();
180 repositorySystemSession.setLocalRepositoryManager(new SimpleLocalRepositoryManagerFactory()
181 .newInstance(repositorySystemSession, new LocalRepository(new File("target/local-repo/"))));
182 MavenSession mavenSession = new MavenSession(
183 getContainer(),
184 repositorySystemSession,
185 mock(MavenExecutionRequest.class),
186 mock(MavenExecutionResult.class));
187
188 setVariableValueToObject(mojo, "session", mavenSession);
189
190
191 setVariableValueToObject(mojo, "createSourcesJar", true);
192
193 RepositorySystem repositorySystem = mock(RepositorySystem.class);
194 setVariableValueToObject(mojo, "repositorySystem", repositorySystem);
195
196 ArtifactResult artifactResult = new ArtifactResult(
197 new ArtifactRequest(mock(org.eclipse.aether.artifact.Artifact.class), Collections.emptyList(), ""));
198 org.eclipse.aether.artifact.Artifact result = new org.eclipse.aether.artifact.DefaultArtifact(
199 "org.apache.myfaces.core:myfaces-impl:jar:sources:2.0.1-SNAPSHOT")
200 .setFile(new File("myfaces-impl-2.0.1-SNAPSHOT-sources.jar"));
201 artifactResult.setArtifact(result);
202 when(repositorySystem.resolveArtifact(eq(mavenSession.getRepositorySession()), any(ArtifactRequest.class)))
203 .thenReturn(artifactResult);
204
205
206 ArchiveFilter archiveFilter = new ArchiveFilter();
207 Field archiveFilterArtifact = ArchiveFilter.class.getDeclaredField("artifact");
208 archiveFilterArtifact.setAccessible(true);
209 archiveFilterArtifact.set(archiveFilter, "org.apache.myfaces.core:myfaces-impl");
210
211
212 Field filtersField = ShadeMojo.class.getDeclaredField("filters");
213 filtersField.setAccessible(true);
214 filtersField.set(mojo, new ArchiveFilter[] {archiveFilter});
215
216
217 Method getFilters = ShadeMojo.class.getDeclaredMethod("getFilters");
218 getFilters.setAccessible(true);
219 List<Filter> filters = (List<Filter>) getFilters.invoke(mojo);
220
221
222 assertEquals(1, filters.size());
223
224
225 Filter filter = filters.get(0);
226 assertTrue(filter.canFilter(new File("myfaces-impl-2.0.1-SNAPSHOT.jar")));
227 assertTrue(filter.canFilter(new File("myfaces-impl-2.0.1-SNAPSHOT-sources.jar")));
228 }
229
230 public void shaderWithPattern(String shadedPattern, File jar) throws Exception {
231 Shader s = lookup(Shader.class);
232
233 Set<File> set = new LinkedHashSet<>();
234
235 set.add(new File(getBasedir(), "src/test/jars/test-project-1.0-SNAPSHOT.jar"));
236
237 set.add(new File(getBasedir(), "src/test/jars/plexus-utils-1.4.1.jar"));
238
239 List<Relocator> relocators = new ArrayList<>();
240
241 relocators.add(new SimpleRelocator(
242 "org/codehaus/plexus/util",
243 shadedPattern,
244 null,
245 Arrays.asList("org/codehaus/plexus/util/xml/Xpp3Dom", "org/codehaus/plexus/util/xml/pull.*")));
246
247 List<ResourceTransformer> resourceTransformers = new ArrayList<>();
248
249 resourceTransformers.add(new ComponentsXmlResourceTransformer());
250
251 List<Filter> filters = new ArrayList<>();
252
253 ShadeRequest shadeRequest = new ShadeRequest();
254 shadeRequest.setJars(set);
255 shadeRequest.setUberJar(jar);
256 shadeRequest.setFilters(filters);
257 shadeRequest.setRelocators(relocators);
258 shadeRequest.setResourceTransformers(resourceTransformers);
259
260 s.shade(shadeRequest);
261 }
262 }