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