6575373: Error verifying signatures of pack200 files in some cases
authorksrini
Wed, 16 Jun 2010 12:36:49 -0700
changeset 5799 e0089b2436a4
parent 5798 9cc262cd2a7a
child 5800 5db7479be994
6575373: Error verifying signatures of pack200 files in some cases Reviewed-by: jrose, forax
jdk/src/share/classes/com/sun/java/util/jar/pack/PropMap.java
jdk/src/share/classes/java/util/jar/Pack200.java
jdk/test/tools/pack200/Pack200Test.java
jdk/test/tools/pack200/SegmentLimit.java
--- 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);
+        }
+    }
+}
+