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.resource;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.File;
23 import java.io.FileOutputStream;
24 import java.io.InputStream;
25 import java.nio.charset.StandardCharsets;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Collections;
29 import java.util.List;
30 import java.util.jar.JarEntry;
31 import java.util.jar.JarFile;
32 import java.util.jar.JarOutputStream;
33
34 import org.apache.commons.io.IOUtils;
35 import org.apache.maven.plugins.shade.relocation.Relocator;
36 import org.apache.maven.plugins.shade.relocation.SimpleRelocator;
37 import org.junit.Test;
38
39 import static org.junit.Assert.assertEquals;
40 import static org.junit.Assert.assertNotNull;
41 import static org.junit.Assert.assertTrue;
42
43
44
45
46 public class ServiceResourceTransformerTest {
47 private final String NEWLINE = "\n";
48
49 private List<Relocator> relocators = new ArrayList<Relocator>();
50
51 @Test
52 public void relocatedClasses() throws Exception {
53 SimpleRelocator relocator =
54 new SimpleRelocator("org.foo", "borg.foo", null, Arrays.asList("org.foo.exclude.*"));
55 relocators.add(relocator);
56
57 String content = "org.foo.Service\norg.foo.exclude.OtherService\n";
58 byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8);
59 InputStream contentStream = new ByteArrayInputStream(contentBytes);
60 String contentResource = "META-INF/services/org.foo.something.another";
61 String contentResourceShaded = "META-INF/services/borg.foo.something.another";
62
63 ServicesResourceTransformer xformer = new ServicesResourceTransformer();
64 xformer.processResource(contentResource, contentStream, relocators, 0);
65 contentStream.close();
66
67 File tempJar = File.createTempFile("shade.", ".jar");
68 tempJar.deleteOnExit();
69 FileOutputStream fos = new FileOutputStream(tempJar);
70 try (JarOutputStream jos = new JarOutputStream(fos)) {
71 xformer.modifyOutputStream(jos);
72 jos.close();
73
74 JarFile jarFile = new JarFile(tempJar);
75 JarEntry jarEntry = jarFile.getJarEntry(contentResourceShaded);
76 assertNotNull(jarEntry);
77 try (InputStream entryStream = jarFile.getInputStream(jarEntry)) {
78 String xformedContent = IOUtils.toString(entryStream, "utf-8");
79 assertEquals("borg.foo.Service" + NEWLINE + "org.foo.exclude.OtherService" + NEWLINE, xformedContent);
80 } finally {
81 jarFile.close();
82 }
83 } finally {
84 tempJar.delete();
85 }
86 }
87
88 @Test
89 public void mergeRelocatedFiles() throws Exception {
90 SimpleRelocator relocator =
91 new SimpleRelocator("org.foo", "borg.foo", null, Collections.singletonList("org.foo.exclude.*"));
92 relocators.add(relocator);
93
94 String content = "org.foo.Service" + NEWLINE + "org.foo.exclude.OtherService" + NEWLINE;
95 String contentShaded = "borg.foo.Service" + NEWLINE + "org.foo.exclude.OtherService" + NEWLINE;
96 byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8);
97 String contentResource = "META-INF/services/org.foo.something.another";
98 String contentResourceShaded = "META-INF/services/borg.foo.something.another";
99
100 ServicesResourceTransformer xformer = new ServicesResourceTransformer();
101
102 try (InputStream contentStream = new ByteArrayInputStream(contentBytes)) {
103 xformer.processResource(contentResource, contentStream, relocators, 0);
104 }
105
106 try (InputStream contentStream = new ByteArrayInputStream(contentBytes)) {
107 xformer.processResource(contentResourceShaded, contentStream, relocators, 0);
108 }
109
110 File tempJar = File.createTempFile("shade.", ".jar");
111 tempJar.deleteOnExit();
112 FileOutputStream fos = new FileOutputStream(tempJar);
113 try (JarOutputStream jos = new JarOutputStream(fos)) {
114 xformer.modifyOutputStream(jos);
115 jos.close();
116
117 JarFile jarFile = new JarFile(tempJar);
118 JarEntry jarEntry = jarFile.getJarEntry(contentResourceShaded);
119 assertNotNull(jarEntry);
120 try (InputStream entryStream = jarFile.getInputStream(jarEntry)) {
121 String xformedContent = IOUtils.toString(entryStream, StandardCharsets.UTF_8);
122 assertEquals(contentShaded, xformedContent);
123 } finally {
124 jarFile.close();
125 }
126 } finally {
127 tempJar.delete();
128 }
129 }
130
131 @Test
132 public void concatanationAppliedMultipleTimes() throws Exception {
133 SimpleRelocator relocator = new SimpleRelocator("org.eclipse", "org.eclipse1234", null, null);
134 relocators.add(relocator);
135
136 String content = "org.eclipse.osgi.launch.EquinoxFactory\n";
137 byte[] contentBytes = content.getBytes("UTF-8");
138 InputStream contentStream = new ByteArrayInputStream(contentBytes);
139 String contentResource = "META-INF/services/org.osgi.framework.launch.FrameworkFactory";
140
141 ServicesResourceTransformer xformer = new ServicesResourceTransformer();
142 xformer.processResource(contentResource, contentStream, relocators, 0);
143 contentStream.close();
144
145 File tempJar = File.createTempFile("shade.", ".jar");
146 tempJar.deleteOnExit();
147 FileOutputStream fos = new FileOutputStream(tempJar);
148 try (JarOutputStream jos = new JarOutputStream(fos)) {
149 xformer.modifyOutputStream(jos);
150 jos.close();
151
152 JarFile jarFile = new JarFile(tempJar);
153 JarEntry jarEntry = jarFile.getJarEntry(contentResource);
154 assertNotNull(jarEntry);
155 try (InputStream entryStream = jarFile.getInputStream(jarEntry)) {
156 String xformedContent = IOUtils.toString(entryStream, StandardCharsets.UTF_8);
157 assertEquals("org.eclipse1234.osgi.launch.EquinoxFactory" + NEWLINE, xformedContent);
158 } finally {
159 jarFile.close();
160 }
161 } finally {
162 tempJar.delete();
163 }
164 }
165
166 @Test
167 public void concatenation() throws Exception {
168 SimpleRelocator relocator = new SimpleRelocator("org.foo", "borg.foo", null, null);
169 relocators.add(relocator);
170
171 String content = "org.foo.Service\n";
172 byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8);
173 InputStream contentStream = new ByteArrayInputStream(contentBytes);
174 String contentResource = "META-INF/services/org.something.another";
175
176 ServicesResourceTransformer xformer = new ServicesResourceTransformer();
177 xformer.processResource(contentResource, contentStream, relocators, 0);
178 contentStream.close();
179
180 content = "org.blah.Service\n";
181 contentBytes = content.getBytes(StandardCharsets.UTF_8);
182 contentStream = new ByteArrayInputStream(contentBytes);
183 contentResource = "META-INF/services/org.something.another";
184
185 xformer.processResource(contentResource, contentStream, relocators, 0);
186 contentStream.close();
187
188 File tempJar = File.createTempFile("shade.", ".jar");
189 tempJar.deleteOnExit();
190 FileOutputStream fos = new FileOutputStream(tempJar);
191 try (JarOutputStream jos = new JarOutputStream(fos)) {
192 xformer.modifyOutputStream(jos);
193 jos.close();
194
195 JarFile jarFile = new JarFile(tempJar);
196 JarEntry jarEntry = jarFile.getJarEntry(contentResource);
197 assertNotNull(jarEntry);
198 try (InputStream entryStream = jarFile.getInputStream(jarEntry)) {
199 String xformedContent = IOUtils.toString(entryStream, "utf-8");
200
201 String[] classes = xformedContent.split("\r?\n");
202 boolean h1 = false;
203 boolean h2 = false;
204 for (String name : classes) {
205 if ("org.blah.Service".equals(name)) {
206 h1 = true;
207 } else if ("borg.foo.Service".equals(name)) {
208 h2 = true;
209 }
210 }
211 assertTrue(h1 && h2);
212 } finally {
213 jarFile.close();
214 }
215 } finally {
216 tempJar.delete();
217 }
218 }
219 }