6575373: Error verifying signatures of pack200 files in some cases
Reviewed-by: jrose, forax
--- a/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java Wed Jun 16 14:24:46 2010 +0100
+++ b/jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java Wed Jun 16 12:36:49 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003,2010 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -90,8 +90,8 @@
props.put(Utils.PACK_DEFAULT_TIMEZONE,
String.valueOf(Boolean.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)));
- // Limit segment size to less than a megabyte.
- props.put(Pack200.Packer.SEGMENT_LIMIT, ""+(1*1000*1000));
+ // The segment size is unlimited
+ props.put(Pack200.Packer.SEGMENT_LIMIT, "");
// Preserve file ordering by default.
props.put(Pack200.Packer.KEEP_FILE_ORDER, Pack200.Packer.TRUE);
--- a/jdk/src/share/classes/java/util/jar/Pack200.java Wed Jun 16 14:24:46 2010 +0100
+++ b/jdk/src/share/classes/java/util/jar/Pack200.java Wed Jun 16 12:36:49 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003,2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -236,9 +236,10 @@
* input file to be transmitted in the segment, along with the size
* of its name and other transmitted properties.
* <p>
- * The default is 1000000 (a million bytes). This allows input JAR files
- * of moderate size to be transmitted in one segment. It also puts
- * a limit on memory requirements for packers and unpackers.
+ * The default is -1, which means the packer will always create a single
+ * segment output file. In cases where extremely large output files are
+ * generated, users are strongly encouraged to use segmenting or break
+ * up the input file into smaller JARs.
* <p>
* A 10Mb JAR packed without this limit will
* typically pack about 10% smaller, but the packer may require
--- a/jdk/test/tools/pack200/Pack200Test.java Wed Jun 16 14:24:46 2010 +0100
+++ b/jdk/test/tools/pack200/Pack200Test.java Wed Jun 16 12:36:49 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,8 +39,8 @@
*/
public class Pack200Test {
- private static ArrayList <File> jarList = new ArrayList();
- private static final String PACKEXT = ".pack";
+ private static ArrayList <File> jarList = new ArrayList<File>();
+ static final String PACKEXT = ".pack";
/** Creates a new instance of Pack200Test */
private Pack200Test() {}
@@ -48,7 +48,7 @@
private static void doPackUnpack() {
for (File in : jarList) {
Pack200.Packer packer = Pack200.newPacker();
- Map p = packer.properties();
+ Map<String, String> p = packer.properties();
// Take the time optimization vs. space
p.put(packer.EFFORT, "1"); // CAUTION: do not use 0.
// Make the memory consumption as effective as possible
@@ -96,7 +96,7 @@
}
private static ArrayList <String> getZipFileEntryNames(ZipFile z) {
- ArrayList <String> out = new ArrayList();
+ ArrayList <String> out = new ArrayList<String>();
for (ZipEntry ze : Collections.list(z.entries())) {
out.add(ze.getName());
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/SegmentLimit.java Wed Jun 16 12:36:49 2010 -0700
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 6575373
+ * @summary verify default segment limit
+ * @compile SegmentLimit.java
+ * @run main SegmentLimit
+ */
+
+import java.io.BufferedReader;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+
+/*
+ * Run this against a large jar file, by default the packer should generate only
+ * one segment, parse the output of the packer to verify if this is indeed true.
+ */
+
+public class SegmentLimit {
+
+ private static final File javaHome = new File(System.getProperty("java.home"));
+
+ public static void main(String... args) {
+ if (!javaHome.getName().endsWith("jre")) {
+ throw new RuntimeException("Error: requires an SDK to run");
+ }
+
+ File out = new File("test" + Pack200Test.PACKEXT);
+ out.delete();
+ runPack200(out);
+ }
+
+ static void close(Closeable c) {
+ if (c == null) {
+ return;
+ }
+ try {
+ c.close();
+ } catch (IOException ignore) {}
+ }
+
+ static void runPack200(File outFile) {
+ File binDir = new File(javaHome, "bin");
+ File pack200Exe = System.getProperty("os.name").startsWith("Windows")
+ ? new File(binDir, "pack200.exe")
+ : new File(binDir, "pack200");
+ File sdkHome = javaHome.getParentFile();
+ File testJar = new File(new File(sdkHome, "lib"), "tools.jar");
+
+ System.out.println("using pack200: " + pack200Exe.getAbsolutePath());
+
+ String[] cmds = { pack200Exe.getAbsolutePath(),
+ "--effort=1",
+ "--verbose",
+ "--no-gzip",
+ outFile.getName(),
+ testJar.getAbsolutePath()
+ };
+ InputStream is = null;
+ BufferedReader br = null;
+ InputStreamReader ir = null;
+
+ FileOutputStream fos = null;
+ PrintStream ps = null;
+
+ try {
+ ProcessBuilder pb = new ProcessBuilder(cmds);
+ pb.redirectErrorStream(true);
+ Process p = pb.start();
+ is = p.getInputStream();
+ ir = new InputStreamReader(is);
+ br = new BufferedReader(ir);
+
+ File logFile = new File("pack200.log");
+ fos = new FileOutputStream(logFile);
+ ps = new PrintStream(fos);
+
+ String line = br.readLine();
+ int count = 0;
+ while (line != null) {
+ line = line.trim();
+ if (line.matches(".*Transmitted.*files of.*input bytes in a segment of.*bytes")) {
+ count++;
+ }
+ ps.println(line);
+ line=br.readLine();
+ }
+ p.waitFor();
+ if (p.exitValue() != 0) {
+ throw new RuntimeException("pack200 failed");
+ }
+ p.destroy();
+ if (count > 1) {
+ throw new Error("test fails: check for multiple segments(" +
+ count + ") in: " + logFile.getAbsolutePath());
+ }
+ } catch (IOException ex) {
+ throw new RuntimeException(ex.getMessage());
+ } catch (InterruptedException ignore){
+ } finally {
+ close(is);
+ close(ps);
+ close(fos);
+ }
+ }
+}
+