1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.compress.harmony.pack200;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertNull;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25
26 import java.io.BufferedReader;
27 import java.io.File;
28 import java.io.FileInputStream;
29 import java.io.FileNotFoundException;
30 import java.io.FileOutputStream;
31 import java.io.FileReader;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.InputStreamReader;
35 import java.net.URISyntaxException;
36 import java.util.Enumeration;
37 import java.util.jar.JarEntry;
38 import java.util.jar.JarFile;
39 import java.util.jar.JarOutputStream;
40
41 import org.apache.commons.compress.AbstractTempDirTest;
42 import org.junit.jupiter.api.Test;
43
44
45
46
47 public class PackingOptionsTest extends AbstractTempDirTest {
48
49 private void compareFiles(final JarFile jarFile, final JarFile jarFile2) throws IOException {
50 final Enumeration<JarEntry> entries = jarFile.entries();
51 while (entries.hasMoreElements()) {
52
53 final JarEntry entry = entries.nextElement();
54 assertNotNull(entry);
55
56 final String name = entry.getName();
57 final JarEntry entry2 = jarFile2.getJarEntry(name);
58 assertNotNull(entry2, "Missing Entry: " + name);
59
60 if (!name.equals("META-INF/MANIFEST.MF")) {
61
62 final InputStream ours = jarFile.getInputStream(entry);
63 final InputStream expected = jarFile2.getInputStream(entry2);
64
65 try (BufferedReader reader1 = new BufferedReader(new InputStreamReader(ours));
66 BufferedReader reader2 = new BufferedReader(new InputStreamReader(expected))) {
67 String line1 = reader1.readLine();
68 String line2 = reader2.readLine();
69 int i = 1;
70 while (line1 != null || line2 != null) {
71 assertEquals(line2, line1, "Unpacked files differ for " + name + " at line " + i);
72 line1 = reader1.readLine();
73 line2 = reader2.readLine();
74 i++;
75 }
76 }
77 }
78 }
79 }
80
81 private void compareJarEntries(final JarFile jarFile, final JarFile jarFile2) {
82 final Enumeration<JarEntry> entries = jarFile.entries();
83 while (entries.hasMoreElements()) {
84
85 final JarEntry entry = entries.nextElement();
86 assertNotNull(entry);
87
88 final String name = entry.getName();
89 final JarEntry entry2 = jarFile2.getJarEntry(name);
90 assertNotNull(entry2, "Missing Entry: " + name);
91 }
92 }
93
94 @Test
95 public void testDeflateHint() {
96
97 final PackingOptions options = new PackingOptions();
98 assertEquals("keep", options.getDeflateHint());
99 options.setDeflateHint("true");
100 assertEquals("true", options.getDeflateHint());
101 options.setDeflateHint("false");
102 assertEquals("false", options.getDeflateHint());
103 assertThrows(IllegalArgumentException.class, () -> options.setDeflateHint("hello"), "Should throw IllegalArgumentException for incorrect deflate hint");
104 }
105
106 @Test
107 public void testErrorAttributes() throws Exception {
108 final File file = createTempFile("unknown", ".pack");
109 try (JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/jndiWithUnknownAttributes.jar").toURI()));
110 FileOutputStream out = new FileOutputStream(file)) {
111 final PackingOptions options = new PackingOptions();
112 options.addClassAttributeAction("Pack200", "error");
113 final Archive ar = new Archive(in, out, options);
114 final Error error = assertThrows(Error.class, () -> {
115 ar.pack();
116 in.close();
117 out.close();
118 });
119 assertEquals("Attribute Pack200 was found", error.getMessage());
120 }
121 }
122
123 @Test
124 public void testKeepFileOrder() throws Exception {
125
126 PackingOptions options = new PackingOptions();
127 assertTrue(options.isKeepFileOrder());
128 options.setKeepFileOrder(false);
129 assertFalse(options.isKeepFileOrder());
130
131
132 File file = createTempFile("sql", ".pack");
133 try (JarFile jarFile = new JarFile(new File(Archive.class.getResource("/pack200/sqlUnpacked.jar").toURI()));
134 FileOutputStream outputStream = new FileOutputStream(file)) {
135 options = new PackingOptions();
136 options.setGzip(false);
137 new Archive(jarFile, outputStream, options).pack();
138 }
139
140 File file2 = createTempFile("sql", ".jar");
141 unpackJar(file, file2);
142
143 File compareFile = new File(Archive.class.getResource("/pack200/sqlUnpacked.jar").toURI());
144 try (JarFile jarFile = new JarFile(file2);
145 JarFile jarFile2 = new JarFile(compareFile)) {
146
147 final Enumeration<JarEntry> entries = jarFile.entries();
148 final Enumeration<JarEntry> entries2 = jarFile2.entries();
149 while (entries.hasMoreElements()) {
150 final JarEntry entry = entries.nextElement();
151 assertNotNull(entry);
152 final JarEntry entry2 = entries2.nextElement();
153 final String name = entry.getName();
154 final String name2 = entry2.getName();
155 assertEquals(name, name2);
156 }
157 }
158
159 file = createTempFile("sql", ".pack");
160 try (JarFile jarFile = new JarFile(new File(Archive.class.getResource("/pack200/sqlUnpacked.jar").toURI()));
161 FileOutputStream outputStream = new FileOutputStream(file);) {
162 options = new PackingOptions();
163 options.setKeepFileOrder(false);
164 options.setGzip(false);
165 new Archive(jarFile, outputStream, options).pack();
166 }
167
168 file2 = createTempFile("sql", ".jar");
169 unpackJar(file, file2);
170
171 compareFile = new File(Archive.class.getResource("/pack200/sqlUnpacked.jar").toURI());
172 try (JarFile jarFile = new JarFile(file2);
173 JarFile jarFile2 = new JarFile(compareFile)) {
174
175 compareJarEntries(jarFile, jarFile2);
176
177 final Enumeration<JarEntry> entries = jarFile.entries();
178 final Enumeration<JarEntry> entries2 = jarFile2.entries();
179 boolean inOrder = true;
180 while (entries.hasMoreElements()) {
181 final JarEntry entry = entries.nextElement();
182 assertNotNull(entry);
183 final JarEntry entry2 = entries2.nextElement();
184 final String name = entry.getName();
185 final String name2 = entry2.getName();
186 if (!name.equals(name2)) {
187 inOrder = false;
188 break;
189 }
190 }
191 assertFalse(inOrder, "Files are not expected to be in order");
192 }
193 }
194
195
196 @Test
197 public void testLoggingOptions() throws Exception {
198
199 final PackingOptions options = new PackingOptions();
200 assertFalse(options.isVerbose());
201 assertNull(options.getLogFile());
202 options.setVerbose(true);
203 assertTrue(options.isVerbose());
204 options.setQuiet(true);
205 assertFalse(options.isVerbose());
206
207 final File logFile = createTempFile("logfile", ".txt");
208 options.setLogFile(logFile.getPath());
209 assertEquals(logFile.getPath(), options.getLogFile());
210
211 File file = createTempFile("helloworld", ".pack.gz");
212 try (JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/hw.jar").toURI()));
213 FileOutputStream out = new FileOutputStream(file)) {
214 new Archive(in, out, options).pack();
215 }
216
217
218 try (FileReader reader = new FileReader(logFile)) {
219 assertFalse(reader.ready());
220 }
221
222 options.setVerbose(true);
223 file = createTempFile("helloworld", ".pack.gz");
224 try (JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/hw.jar").toURI()));
225 FileOutputStream out = new FileOutputStream(file)) {
226 new Archive(in, out, options).pack();
227 }
228
229
230 try (FileReader reader = new FileReader(logFile)) {
231 assertTrue(reader.ready());
232 }
233 PackingUtils.config(null);
234 }
235
236 @Test
237 public void testModificationTime() throws Exception {
238
239 PackingOptions options = new PackingOptions();
240 assertEquals("keep", options.getModificationTime());
241 options.setModificationTime("latest");
242 assertEquals("latest", options.getModificationTime());
243 assertThrows(IllegalArgumentException.class, () -> {
244 final PackingOptions illegalOption = new PackingOptions();
245 illegalOption.setModificationTime("true");
246 }, "Should throw IllegalArgumentException for incorrect mod time");
247
248
249 File file = createTempFile("sql", ".pack");
250 try (JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/sqlUnpacked.jar").toURI()));
251 FileOutputStream out = new FileOutputStream(file)) {
252 options = new PackingOptions();
253 options.setGzip(false);
254 new Archive(in, out, options).pack();
255 }
256
257 File file2 = createTempFile("sql", ".jar");
258 unpackJar(file, file2);
259
260 File compareFile = new File(Archive.class.getResource("/pack200/sqlUnpacked.jar").toURI());
261 try (JarFile jarFile = new JarFile(file2);
262 JarFile jarFile2 = new JarFile(compareFile)) {
263
264 final Enumeration<JarEntry> entries = jarFile.entries();
265 final Enumeration<JarEntry> entries2 = jarFile2.entries();
266 while (entries.hasMoreElements()) {
267
268 final JarEntry entry = entries.nextElement();
269 assertNotNull(entry);
270 final JarEntry entry2 = entries2.nextElement();
271 final String name = entry.getName();
272 final String name2 = entry2.getName();
273 assertEquals(name, name2);
274 assertEquals(entry.getTime(), entry2.getTime());
275 }
276 }
277
278 file = createTempFile("sql", ".pack");
279 try (JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/sqlUnpacked.jar").toURI()));
280 FileOutputStream out = new FileOutputStream(file)) {
281 options = new PackingOptions();
282 options.setGzip(false);
283 options.setModificationTime("latest");
284 new Archive(in, out, options).pack();
285 }
286
287 file2 = createTempFile("sql", ".jar");
288 unpackJar(file, file2);
289
290 compareFile = new File(Archive.class.getResource("/pack200/sqlUnpacked.jar").toURI());
291 try (JarFile jarFile = new JarFile(file2);
292 JarFile jarFile2 = new JarFile(compareFile)) {
293
294 final Enumeration<JarEntry> entries = jarFile.entries();
295 final Enumeration<JarEntry> entries2 = jarFile2.entries();
296 long modtime = -1;
297 boolean sameAsOriginal = true;
298 while (entries.hasMoreElements()) {
299 final JarEntry entry = entries.nextElement();
300 assertNotNull(entry);
301 final JarEntry entry2 = entries2.nextElement();
302 final String name = entry.getName();
303 if (!name.startsWith("META-INF")) {
304 if (modtime == -1) {
305 modtime = entry.getTime();
306 } else {
307 assertEquals(modtime, entry.getTime());
308 }
309 }
310 if (entry2.getTime() != entry.getTime()) {
311 sameAsOriginal = false;
312 }
313 }
314 assertFalse(sameAsOriginal, "Some modtimes should have changed");
315 }
316 }
317
318 @Test
319 public void testNewAttributes() throws Exception {
320 final File file = createTempFile("unknown", ".pack");
321 try (FileOutputStream out = new FileOutputStream(file);
322 JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/jndiWithUnknownAttributes.jar").toURI()))) {
323 final PackingOptions options = new PackingOptions();
324 options.addClassAttributeAction("Pack200", "I");
325 new Archive(in, out, options).pack();
326 }
327
328
329 final File file2 = createTempFile("unknown", ".jar");
330 unpackJar(file, file2);
331
332 final File compareFile = new File(Archive.class.getResource("/pack200/jndiWithUnknownAttributes.jar").toURI());
333 try (JarFile jarFile = new JarFile(file2);
334 JarFile jarFile2 = new JarFile(compareFile)) {
335 assertEquals(jarFile2.size(), jarFile.size());
336 compareJarEntries(jarFile, jarFile2);
337
338 }
339 }
340
341 @Test
342 public void testNewAttributes2() throws Exception {
343 final File file = createTempFile("unknown", ".pack");
344 try (FileOutputStream out = new FileOutputStream(file);
345 JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/p200WithUnknownAttributes.jar").toURI()))) {
346 final PackingOptions options = new PackingOptions();
347 options.addFieldAttributeAction("Pack200", "I");
348 options.addMethodAttributeAction("Pack200", "I");
349 options.addCodeAttributeAction("Pack200", "I");
350 final Archive ar = new Archive(in, out, options);
351 ar.pack();
352 }
353
354 final File file2 = createTempFile("unknown", ".jar");
355 unpackJar(file, file2);
356
357
358 final File compareFile = new File(Archive.class.getResource("/pack200/p200WithUnknownAttributes.jar").toURI());
359 try (JarFile jarFile = new JarFile(file2);
360 JarFile jarFile2 = new JarFile(compareFile)) {
361 assertEquals(jarFile2.size(), jarFile.size());
362 compareJarEntries(jarFile, jarFile2);
363 }
364 }
365
366 @Test
367 public void testPackEffort0() throws Pack200Exception, IOException, URISyntaxException {
368 final File f1 = new File(Archive.class.getResource("/pack200/jndi.jar").toURI());
369 final File file = createTempFile("jndiE0", ".pack");
370 try (JarFile in = new JarFile(f1);
371 FileOutputStream out = new FileOutputStream(file)) {
372 final PackingOptions options = new PackingOptions();
373 options.setGzip(false);
374 options.setEffort(0);
375 new Archive(in, out, options).pack();
376 }
377 try (JarFile jf1 = new JarFile(f1);
378 JarFile jf2 = new JarFile(file)) {
379 compareFiles(jf1, jf2);
380 }
381 }
382
383 @Test
384 public void testPassAttributes() throws Exception {
385 final File file = createTempFile("unknown", ".pack");
386 try (FileOutputStream out = new FileOutputStream(file);
387 JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/jndiWithUnknownAttributes.jar").toURI()))) {
388 final PackingOptions options = new PackingOptions();
389 options.addClassAttributeAction("Pack200", "pass");
390 new Archive(in, out, options).pack();
391 }
392
393
394 final File file2 = createTempFile("unknown", ".jar");
395 unpackJar(file, file2);
396
397
398 final File compareFile = new File(Archive.class.getResource("/pack200/jndiWithUnknownAttributes.jar").toURI());
399 try (JarFile jarFile = new JarFile(file2);
400 JarFile jarFile2 = new JarFile(compareFile)) {
401 assertEquals(jarFile2.size(), jarFile.size());
402 compareJarEntries(jarFile, jarFile2);
403 }
404 }
405
406 @Test
407 public void testPassFiles() throws IOException, URISyntaxException, Pack200Exception {
408
409 final File file0 = createTempFile("sql", ".pack");
410 try (JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/sqlUnpacked.jar").toURI()));
411 FileOutputStream out = new FileOutputStream(file0)) {
412 final PackingOptions options = new PackingOptions();
413 options.setGzip(false);
414 new Archive(in, out, options).pack();
415 }
416
417
418 final File file = createTempFile("sql", ".pack");
419 try (JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/sqlUnpacked.jar").toURI()));
420 FileOutputStream out = new FileOutputStream(file)) {
421 final PackingOptions options = new PackingOptions();
422 options.setGzip(false);
423 options.addPassFile("bin/test/org/apache/harmony/sql/tests/java/sql/DatabaseMetaDataTest.class");
424 assertTrue(options.isPassFile("bin/test/org/apache/harmony/sql/tests/java/sql/DatabaseMetaDataTest.class"));
425 new Archive(in, out, options).pack();
426 }
427
428
429 final File file2 = createTempFile("sql", ".pack");
430 try (JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/sqlUnpacked.jar").toURI()));
431 FileOutputStream out = new FileOutputStream(file2)) {
432 final PackingOptions options = new PackingOptions();
433 options.setGzip(false);
434 options.addPassFile("bin/test/org/apache/harmony/sql/tests/java/sql");
435 assertTrue(options.isPassFile("bin/test/org/apache/harmony/sql/tests/java/sql/DatabaseMetaDataTest.class"));
436 assertFalse(options.isPassFile("bin/test/org/apache/harmony/sql/tests/java/sqldata/SqlData.class"));
437 new Archive(in, out, options).pack();
438 }
439
440 assertTrue(file.length() > file0.length(), "If files are passed then the pack file should be larger");
441 assertTrue(file2.length() > file.length(), "If more files are passed then the pack file should be larger");
442
443
444 final File file3 = createTempFile("sql", ".jar");
445 unpackJar(file, file3);
446
447 final File compareFile = new File(Archive.class.getResource("/pack200/sqlUnpacked.jar").toURI());
448 try (JarFile jarFile = new JarFile(file3);
449 JarFile jarFile2 = new JarFile(compareFile)) {
450
451 compareJarEntries(jarFile, jarFile2);
452 }
453
454 final File file4 = createTempFile("sql", ".jar");
455 unpackJar(file2, file4);
456
457 try (JarFile jarFile = new JarFile(file4);
458 JarFile jarFile2 = new JarFile(compareFile)) {
459 compareJarEntries(jarFile, jarFile2);
460 }
461 }
462
463 @Test
464 public void testSegmentLimits() throws IOException, Pack200Exception, URISyntaxException {
465 File file = createTempFile("helloworld", ".pack.gz");
466 try (JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/hw.jar").toURI()));
467 FileOutputStream out = new FileOutputStream(file)) {
468 final PackingOptions options = new PackingOptions();
469 options.setSegmentLimit(0);
470 final Archive archive = new Archive(in, out, options);
471 archive.pack();
472 }
473
474 file = createTempFile("helloworld", ".pack.gz");
475 try (JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/hw.jar").toURI()));
476 FileOutputStream out = new FileOutputStream(file)) {
477 final PackingOptions options = new PackingOptions();
478 options.setSegmentLimit(-1);
479 new Archive(in, out, options).pack();
480 }
481
482 file = createTempFile("helloworld", ".pack.gz");
483 try (JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/hw.jar").toURI()));
484 FileOutputStream out = new FileOutputStream(file)) {
485 final PackingOptions options = new PackingOptions();
486 options.setSegmentLimit(5000);
487 new Archive(in, out, options).pack();
488 }
489 }
490
491 @Test
492 public void testStripDebug() throws IOException, Pack200Exception, URISyntaxException {
493 final File file = createTempFile("sql", ".pack");
494 try (JarFile in = new JarFile(new File(Archive.class.getResource("/pack200/sqlUnpacked.jar").toURI()));
495 FileOutputStream out = new FileOutputStream(file)) {
496 final PackingOptions options = new PackingOptions();
497 options.setGzip(false);
498 options.setStripDebug(true);
499 final Archive archive = new Archive(in, out, options);
500 archive.pack();
501 }
502
503
504 final File file2 = createTempFile("sqloutNoDebug", ".jar");
505 unpackJar(file, file2);
506
507 final File compareFile = new File(Archive.class.getResource("/pack200/sqlUnpackedNoDebug.jar").toURI());
508 try (JarFile jarFile = new JarFile(file2);
509 JarFile jarFile2 = new JarFile(compareFile)) {
510 assertTrue(file2.length() < 250000);
511 compareFiles(jarFile, jarFile2);
512 }
513 }
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531 private void unpack(final InputStream inputStream, final JarOutputStream outputStream) throws Pack200Exception, IOException {
532 new org.apache.commons.compress.harmony.unpack200.Archive(inputStream, outputStream).unpack();
533 }
534
535 private void unpackJar(final File sourceFile, final File destFile) throws Pack200Exception, IOException, FileNotFoundException {
536 try (InputStream in2 = new FileInputStream(sourceFile);
537 JarOutputStream out2 = new JarOutputStream(new FileOutputStream(destFile))) {
538 unpack(in2, out2);
539 }
540 }
541
542 }