--- a/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Fri Nov 20 19:26:16 2015 +0100
+++ b/jdk/src/java.base/share/classes/com/sun/java/util/jar/pack/PackerImpl.java Mon Sep 28 08:42:06 2015 -0700
@@ -272,22 +272,6 @@
// (Done collecting options from props.)
- boolean isClassFile(String name) {
- if (!name.endsWith(".class")) return false;
- for (String prefix = name; ; ) {
- if (passFiles.contains(prefix)) return false;
- int chop = prefix.lastIndexOf('/');
- if (chop < 0) break;
- prefix = prefix.substring(0, chop);
- }
- return true;
- }
-
- boolean isMetaInfFile(String name) {
- return name.startsWith("/" + Utils.METAINF) ||
- name.startsWith(Utils.METAINF);
- }
-
// Get a new package, based on the old one.
private void makeNextPackage() {
pkg.reset();
@@ -332,6 +316,29 @@
InFile(JarEntry je) {
this(null, je);
}
+ boolean isClassFile() {
+ if (!name.endsWith(".class")) {
+ return false;
+ }
+ for (String prefix = name;;) {
+ if (passFiles.contains(prefix)) {
+ return false;
+ }
+ int chop = prefix.lastIndexOf('/');
+ if (chop < 0) {
+ break;
+ }
+ prefix = prefix.substring(0, chop);
+ }
+ return true;
+ }
+ boolean isMetaInfFile() {
+ return name.startsWith("/" + Utils.METAINF)
+ || name.startsWith(Utils.METAINF);
+ }
+ boolean mustProcess() {
+ return !isMetaInfFile() && isClassFile();
+ }
long getInputLength() {
long len = (je != null)? je.getSize(): f.length();
assert(len >= 0) : this+".len="+len;
@@ -391,7 +398,7 @@
Package.File file = null;
// (5078608) : discount the resource files in META-INF
// from segment computation.
- long inflen = (isMetaInfFile(name))
+ long inflen = (inFile.isMetaInfFile())
? 0L
: inFile.getInputLength();
@@ -406,7 +413,7 @@
assert(je.isDirectory() == name.endsWith("/"));
- if (isClassFile(name)) {
+ if (inFile.mustProcess()) {
file = readClass(name, bits.getInputStream());
}
if (file == null) {
@@ -429,7 +436,7 @@
for (InFile inFile : inFiles) {
String name = inFile.name;
// (5078608) : discount the resource files completely from segmenting
- long inflen = (isMetaInfFile(name))
+ long inflen = (inFile.isMetaInfFile())
? 0L
: inFile.getInputLength() ;
if ((segmentSize += inflen) > segmentLimit) {
@@ -447,7 +454,7 @@
if (verbose > 1)
Utils.log.fine("Reading " + name);
Package.File file = null;
- if (isClassFile(name)) {
+ if (inFile.mustProcess()) {
file = readClass(name, strm);
if (file == null) {
strm.close();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/pack200/MultiRelease.java Mon Sep 28 08:42:06 2015 -0700
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2015, 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).
+ *
+ r 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.
+ */
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+ * @test
+ * @bug 8066272
+ * @summary tests a simple multi-versioned jar file
+ * @compile -XDignore.symbol.file Utils.java MultiRelease.java
+ * @run main MultiRelease
+ * @author ksrini
+ */
+
+public class MultiRelease {
+ private static final File cwd = new File(".");
+ private static int pass = 0;
+ private static int fail = 0;
+ // specify alternate name via arguments to verify
+ // if permanent fix works
+
+ private static final String PropKey = "pack200.MultiRelease.META-INF";
+ private static final String MetaInfName = System.getProperty(PropKey, "META-INF");
+
+ public static void main(String... args) throws Exception {
+ new MultiRelease().run();
+ }
+
+ void run() throws Exception {
+ List<TestCase> testCases = new ArrayList<>();
+ testCases.add(new TestCase1());
+ testCases.add(new TestCase2());
+ for (TestCase tc : testCases) {
+ tc.run();
+ }
+ if (fail > 0) {
+ throw new Exception(fail + "/" + testCases.size() + " tests fails");
+ } else {
+ System.out.println("All tests(" + pass + ") passes");
+ }
+ }
+
+ /*
+ * An abstract class to eliminate test boiler plating.
+ */
+ static abstract class TestCase {
+ final File tcwd;
+ final File metaInfDir;
+ final File versionsDir;
+ final File manifestFile;
+
+ TestCase(String directory) throws IOException {
+ System.out.println("initializing directories");
+ tcwd = new File(cwd, directory);
+ metaInfDir = mkdir(new File(tcwd, MetaInfName));
+ versionsDir = mkdir(new File(metaInfDir, "versions"));
+ manifestFile = new File(tcwd, "manifest.tmp");
+ List<String> scratch = new ArrayList<>();
+ scratch.add("Multi-Release: true");
+ Utils.createFile(manifestFile, scratch);
+ }
+
+ File mkdir(File f) throws IOException {
+ if (f.exists() && f.isDirectory() && f.canRead() && f.canWrite()) {
+ return f;
+ }
+ if (!f.mkdirs()) {
+ throw new IOException("mkdirs failed: " + f.getAbsolutePath());
+ }
+ return f;
+ }
+
+ abstract void emitClassFiles() throws Exception;
+
+ void run() {
+ try {
+ emitClassFiles();
+ // jar the file up
+ File testFile = new File(tcwd, "test" + Utils.JAR_FILE_EXT);
+ Utils.jar("cvfm",
+ testFile.getAbsolutePath(),
+ manifestFile.getAbsolutePath(),
+ "-C",
+ tcwd.getAbsolutePath(),
+ ".");
+ File outFile = new File(tcwd, "test-repacked" + Utils.JAR_FILE_EXT);
+ List<String> cmdsList = new ArrayList<>();
+
+ cmdsList.add(Utils.getPack200Cmd());
+ cmdsList.add("-J-ea");
+ cmdsList.add("-J-esa");
+ cmdsList.add("-v");
+ cmdsList.add("--repack");
+ cmdsList.add(outFile.getAbsolutePath());
+ cmdsList.add(testFile.getAbsolutePath());
+ List<String> output = Utils.runExec(cmdsList);
+ Utils.doCompareVerify(testFile.getAbsoluteFile(), outFile.getAbsoluteFile());
+ pass++;
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ fail++;
+ }
+ }
+ }
+
+ static class TestCase1 extends TestCase {
+ private TestCase1(String directory) throws IOException {
+ super(directory);
+ }
+
+ public TestCase1() throws Exception {
+ this("case1");
+ }
+
+ @Override
+ void emitClassFiles() throws Exception {
+ emitClassFile("");
+ emitClassFile("7");
+ emitClassFile("8");
+ emitClassFile("9");
+ }
+
+ /*
+ * Adds different variants of types
+ */
+ void emitClassFile(String version) throws IOException {
+ final File outDir = mkdir(version.isEmpty()
+ ? tcwd
+ : new File(versionsDir, version));
+
+ final File srcDir = mkdir(version.isEmpty()
+ ? new File(tcwd, "src")
+ : new File(new File(versionsDir, version), "src"));
+
+ final String fname = "Foo";
+ final File srcFile = new File(srcDir, fname + Utils.JAVA_FILE_EXT);
+ List<String> scratch = new ArrayList<>();
+
+ scratch.add("package pkg;");
+ switch (version) {
+ case "7":
+ scratch.add("public class Foo {");
+ scratch.add("public static final class Bar {}");
+ break;
+ case "8":
+ scratch.add("public abstract class Foo {");
+ scratch.add("public final class Bar {}");
+ break;
+ case "9":
+ scratch.add("public interface Foo {");
+ scratch.add("public final class Bar {}");
+ break;
+ default:
+ scratch.add("public class Foo {");
+ scratch.add("public final class Bar {}");
+ break;
+ }
+ scratch.add("}");
+
+ Utils.createFile(srcFile, scratch);
+ Utils.compiler("-d",
+ outDir.getAbsolutePath(),
+ srcFile.getAbsolutePath());
+ }
+ }
+
+ static class TestCase2 extends TestCase {
+ private TestCase2(String directory) throws IOException {
+ super(directory);
+ }
+
+ TestCase2() throws Exception {
+ this("case2");
+ }
+
+ @Override
+ void emitClassFiles() throws Exception {
+ emitClassFile("");
+ emitClassFile("8");
+ }
+
+ /*
+ * Adds different variants of types and tries to invoke an
+ * interface or concrete method defined by them.
+ */
+ void emitClassFile(String version) throws IOException {
+
+ final File outDir = mkdir(version.isEmpty()
+ ? tcwd
+ : new File(versionsDir, version));
+
+ final File srcDir = mkdir(version.isEmpty()
+ ? new File(tcwd, "src")
+ : new File(new File(versionsDir, version), "src"));
+
+ List<String> scratch = new ArrayList<>();
+ final String fname1 = "Ab";
+ final File srcFile1 = new File(srcDir, fname1 + Utils.JAVA_FILE_EXT);
+
+ final String fname2 = "AbNormal";
+ final File srcFile2 = new File(srcDir, fname2 + Utils.JAVA_FILE_EXT);
+ switch (version) {
+ case "8":
+ scratch.clear();
+ scratch.add("import java.io.IOException;");
+ scratch.add("public interface " + fname1 + "{");
+ scratch.add(" public abstract void close() throws IOException ;");
+ scratch.add("}");
+ Utils.createFile(srcFile1, scratch);
+ break;
+ default:
+ scratch.clear();
+ scratch.add("import java.io.IOException;");
+ scratch.add("public abstract class " + fname1 + "{");
+ scratch.add(" public abstract void close() throws IOException ;");
+ scratch.add("}");
+ Utils.createFile(srcFile1, scratch);
+ }
+
+ scratch.clear();
+ scratch.add("import java.io.IOException;");
+ scratch.add("public class " + fname2 + "{");
+ scratch.add(" public void doSomething(Ab ab) throws IOException {");
+ scratch.add(" ab.close();");
+ scratch.add(" }");
+ scratch.add("}");
+
+ Utils.createFile(srcFile2, scratch);
+ Utils.compiler("-d",
+ outDir.getAbsolutePath(),
+ srcFile1.getAbsolutePath(),
+ srcFile2.getAbsolutePath());
+ }
+ }
+}