PATCH [6901992] : Possible InvalidJarIndexException due to bug in sun.misc.JarIndex.merge()
Diego Belfer
dbelfer at gmail.com
Wed Jun 13 05:11:23 UTC 2012
Hi,
I have finally reproduced the InvalidJarIndexException bug as reported in
the ticket. I mentioned in a previous email, that the only way I'd found
for getting the error was to use an invalid index file (INDEX.LIST), which
did not have any sense. That's because I was using jars containing
"directory entries" (I was unaware that jar files may not include them)
After reviewing the URLClasspath$JarLoader class and the validIndex method,
I notice it is possible to get the exception for a Jar file which does not
include directory entries. In order to trigger the issue, the Jar must be
referenced by an intermediary INDEX.LIST and the intermediary Jar index
should have been merged to its parent index. Although, jar tool includes
directory entries in the generated jar files, Eclipse default option for
exporting jars does not include them (AFAIK), so this might be quite common.
I have created a new PATCH which includes an additional test case which
uses the URLClassLoader to trigger the InvalidIndexException.
The patch is attached, please consider it for review.
Best,
Diego Belfer [muralx]
On Mon, Jun 11, 2012 at 4:47 PM, Diego Belfer <dbelfer at gmail.com> wrote:
> Hi,
>
> Here is a patch that fixes the merge method of the JarIndex. This bug was
> reported as the cause of the bug 6901992. Although, I was not able to
> reproduce the BUG itself (InvalidJarIndexException), I did verified that
> the method had a bug, and resources/classes where not found in a jarIndex
> with merged contents.
>
> If you think it is possible to commit this fix without actually
> reproducing the original bug report, please consider this patch for review.
>
> Thanks,
> Diego Belfer [muralx]
>
>
-------------- next part --------------
# HG changeset patch
# User muralx
# Date 1339560937 10800
# Node ID 26467341e7232b981f96ecdf80d3b6cd649e61f1
# Parent fc575c78f5d314fd8ccbdc86c8b2d7631d736960
[PATCH] 6901992 - Possible InvalidJarIndexException due to bug in sun.misc.JarIndex.merge()
diff --git a/src/share/classes/sun/misc/JarIndex.java b/src/share/classes/sun/misc/JarIndex.java
--- a/src/share/classes/sun/misc/JarIndex.java
+++ b/src/share/classes/sun/misc/JarIndex.java
@@ -201,23 +201,20 @@
packageName = fileName;
}
- // add the mapping to indexMap
- addToList(packageName, jarName, indexMap);
-
- // add the mapping to jarMap
- addToList(jarName, packageName, jarMap);
+ addMapping(packageName, jarName);
}
/**
* Same as add(String,String) except that it doesn't strip off from the
- * last index of '/'. It just adds the filename.
+ * last index of '/'. It just adds the jarItem (filename or package)
+ * as it is received.
*/
- private void addExplicit(String fileName, String jarName) {
+ private void addMapping(String jarItem, String jarName) {
// add the mapping to indexMap
- addToList(fileName, jarName, indexMap);
+ addToList(jarItem, jarName, indexMap);
// add the mapping to jarMap
- addToList(jarName, fileName, jarMap);
+ addToList(jarName, jarItem, jarMap);
}
/**
@@ -248,18 +245,14 @@
fileName.equals(JarFile.MANIFEST_NAME))
continue;
- if (!metaInfFilenames) {
+ if (!metaInfFilenames || !fileName.startsWith("META-INF/")) {
add(fileName, currentJar);
- } else {
- if (!fileName.startsWith("META-INF/")) {
- add(fileName, currentJar);
- } else if (!entry.isDirectory()) {
+ } else if (!entry.isDirectory()) {
// Add files under META-INF explicitly so that certain
// services, like ServiceLoader, etc, can be located
// with greater accuracy. Directories can be skipped
// since each file will be added explicitly.
- addExplicit(fileName, currentJar);
- }
+ addMapping(fileName, currentJar);
}
}
@@ -324,8 +317,7 @@
jars.add(currentJar);
} else {
String name = line;
- addToList(name, currentJar, indexMap);
- addToList(currentJar, name, jarMap);
+ addMapping(name, currentJar);
}
}
@@ -354,7 +346,7 @@
if (path != null) {
jarName = path.concat(jarName);
}
- toIndex.add(packageName, jarName);
+ toIndex.addMapping(packageName, jarName);
}
}
}
diff --git a/test/sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java b/test/sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java
new file mode 100644
--- /dev/null
+++ b/test/sun/misc/JarIndex/JarIndexMergeForClassLoaderTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2012, 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 6901992
+ * @summary Possible InvalidJarIndexException due to bug in sun.misc.JarIndex.merge()
+ * @author Diego Belfer
+ */
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+public class JarIndexMergeForClassLoaderTest {
+ static final String slash = File.separator;
+ static final String testSrc = System.getProperty("test.src");
+ static final String testSrcDir = testSrc != null ? testSrc : ".";
+
+ public static void main(String[] args) throws Exception {
+ String file = testSrcDir + slash + "jarIndexMerge" + slash
+ + "level1.jar";
+ URL url = new File(file).toURI().toURL();
+
+ URLClassLoader classLoader = new URLClassLoader(new URL[] { url });
+
+ // We preload level2.jar using a package available in it
+ if (classLoader.getResource("sub/test/pck2/x.x") != null) {
+ throw new RuntimeException("Null expected for getResource");
+ }
+ // Now we have no-dir-entries index in the classloader, we check if it
+ // works as expected
+ if (classLoader.getResource("com/resource.file") != null) {
+ throw new RuntimeException("Null expected for getResource");
+ }
+ if (classLoader.getResource("com/test/resource.file") == null) {
+ throw new RuntimeException("Expected resource URL");
+ }
+ }
+}
+
diff --git a/test/sun/misc/JarIndex/JarIndexMergeTest.java b/test/sun/misc/JarIndex/JarIndexMergeTest.java
new file mode 100644
--- /dev/null
+++ b/test/sun/misc/JarIndex/JarIndexMergeTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, 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 6901992
+ * @summary Possible InvalidJarIndexException due to bug in sun.misc.JarIndex.merge()
+ * @author Diego Belfer
+ */
+
+import java.io.File;
+import java.util.LinkedList;
+
+import sun.misc.JarIndex;
+
+ at SuppressWarnings("restriction")
+public class JarIndexMergeTest {
+ static final String slash = File.separator;
+ static final String testSrc = System.getProperty("test.src");
+ static final String testSrcDir = testSrc != null ? testSrc : ".";
+
+ public static void main(String[] args) throws Exception {
+
+ JarIndex jarIndexMissing = new JarIndex(
+ new String[] { testSrcDir + slash + "jarIndexMerge" + slash + "missing.jar" });
+ LinkedList jarLists = jarIndexMissing
+ .get("fail/subdir/resourceToSearch.properties");
+ if (jarLists != null && jarLists.size() > 0) {
+ throw new RuntimeException(
+ "Unexpected result: missing.jar should not contain the required file");
+ }
+
+ String containerJarName = testSrcDir + slash +"jarIndexMerge" + slash + "container.jar";
+ JarIndex jarIndexContainer = new JarIndex(
+ new String[] { containerJarName });
+ jarLists = jarIndexContainer
+ .get("fail/subdir/resourceToSearch.properties");
+ if (jarLists == null || jarLists.size() == 0) {
+ throw new RuntimeException(
+ "Unexpected result: container.jar should contain the required file");
+ }
+
+ // We merge the index into the jarIndexMissing
+ jarIndexContainer.merge(jarIndexMissing, null);
+
+ jarLists = jarIndexMissing
+ .get("fail/subdir/resourceToSearch.properties");
+ if (jarLists == null || jarLists.size() == 0 || !containerJarName.equals(jarLists.get(0))) {
+ throw new RuntimeException(
+ "Unexpected result: the merged index should contain the required file");
+ }
+ }
+
+}
diff --git a/test/sun/misc/JarIndex/jarIndexMerge/container.jar b/test/sun/misc/JarIndex/jarIndexMerge/container.jar
new file mode 100644
index 0000000000000000000000000000000000000000..303f44f36498380ed59aa734530da52ae7bf2c0a
GIT binary patch
literal 362
zc$^FHW at h1H00G79Qw|JBfE9?-5;Jr31K>&w(UkDOloXdHrDPW2QK^omvM9AUzqBYh
zH6%YcHL)l;L$9DHzaX`!Br~-*z?+eYivhQrPyy712rby$hycnMF2=1>9Yv=vDL!Cj
P18HFf!b3oM64(F$sMkDM
diff --git a/test/sun/misc/JarIndex/jarIndexMerge/level1.jar b/test/sun/misc/JarIndex/jarIndexMerge/level1.jar
new file mode 100644
index 0000000000000000000000000000000000000000..5fd50b111399e525a11b4ed48d643509156b27e0
GIT binary patch
literal 627
zc$^FHW at Zs#-~htq3}+n}kbp1)3xls~h at -BjpPRm?pNngRo{wj6$iGtz44=JpKArLQ
zTzi4nTUYDcne&^246YbIcy!8B*ZZvDmD652kF at lBnG*j_y7EZK!g;@f<!z2tXF3)b
zF$8$Cb0jzOI9dYDPX*!tpzT~>+t#O?Lb06%h>J^;^bsmHpsC=5swhb<E<sXu5=|K&
zva*8YY$H5sr7+Yc=Oh*vo9Kb50B=Sn5e7tHA$vp^>|kVoBj`Yea53QaGXm7XLja)z
tTNog~0 at M&eXu}pJ2yh%r2;tT%g`)Q}fe>S51F2#KLL){725m+V4*(#*bsGQx
diff --git a/test/sun/misc/JarIndex/jarIndexMerge/level2.jar b/test/sun/misc/JarIndex/jarIndexMerge/level2.jar
new file mode 100644
index 0000000000000000000000000000000000000000..563b5d1230b8dfea1e2d4fe9706a7d7471083b63
GIT binary patch
literal 645
zc$^FHW at Zs#-~hta3}+n}kbp1)3xls~h at -BjpPRm?pNngRo{wj6$iGtz44=JpKArLQ
zTzi4nTUYDcne&^246YbIcy!8B*ZZvDrPE$IkF at lBnG*j_y7EZK!g;@f<?W7cZGC&y
z%^v2a>z8O4Z<SbMWoa+IXc9L=fHylw%GqOAyn!}G0dWA(JzQY>@1~qWaSsa+7ndgK
zBUFf{qN?D8swhb<F44zr5FfI#g5+!?JZhyd)F$U778e`qfvEs*MkWykMDQVdL>TN~
zWPl?uL56TK;Px{DOn`>~LI<`mK!8oCA%fc?J``;?v4jwAy;3N8SsC$%7%LlC6%ZN$
JRoXIwcmSi>e7^ty
diff --git a/test/sun/misc/JarIndex/jarIndexMerge/missing.jar b/test/sun/misc/JarIndex/jarIndexMerge/missing.jar
new file mode 100644
index 0000000000000000000000000000000000000000..2fa7239cda88c54666f1047a4862d56dc26b23ab
GIT binary patch
literal 316
zc$^FHW at h1H0D<=@ryLlN04op|mnIqN2f&qRr=lw1f+;CUEiS>MP6$O^QEIVXT4qja
vfHxx(7Xxm~Q32E`2rbwgg8<5CPQ$HF2t}Va4yUrRfn=G1a5a#w2CD at CHj62z
diff --git a/test/sun/misc/JarIndex/jarIndexMerge/nodir-entries.jar b/test/sun/misc/JarIndex/jarIndexMerge/nodir-entries.jar
new file mode 100644
index 0000000000000000000000000000000000000000..136162d60b08ed176c1d855f8ca97ec5778d7bb7
GIT binary patch
literal 327
zc$^FHW at Zs#;Nak3&|*02z<>lq7+4s5T|*poJ^kGDeI5Ng-CTo1^nBg^onm14?0e?4
zkGHPgMP6 at Rt#fD2Zw at lJV*KFgqo+&^0p9E!o9da~Ndt|L1mXa=1>(EUpjaRV#L4-&
z`X#BwCHh6F#rdU0$*Fp2nK`M<U{gS9n4oF{ycwB97!VFcwgKc&RDjFb$fm$t!-V7-
X1W3f`wg7KdHi$kZhAtqz9IPGy2WdY-
More information about the core-libs-dev
mailing list