This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push:
new e2a00ea91f Fix bloom filter index for JARs in packed WARs
e2a00ea91f is described below
commit e2a00ea91fc5f36e1070f796486ac0860dee0a96
Author: Mark Thomas <[email protected]>
AuthorDate: Tue Jul 22 15:39:35 2025 +0100
Fix bloom filter index for JARs in packed WARs
---
.../webresources/AbstractArchiveResourceSet.java | 8 +-
.../apache/catalina/webresources/JarContents.java | 96 +++++++++++++---------
.../catalina/webresources/JarWarResourceSet.java | 24 ++++++
webapps/docs/changelog.xml | 15 +---
4 files changed, 88 insertions(+), 55 deletions(-)
diff --git
a/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java
b/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java
index d73deee956..2180d0806d 100644
--- a/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java
+++ b/java/org/apache/catalina/webresources/AbstractArchiveResourceSet.java
@@ -36,12 +36,12 @@ public abstract class AbstractArchiveResourceSet extends
AbstractResourceSet {
private URL baseUrl;
private String baseUrlString;
- private JarFile archive = null;
+ protected JarFile archive = null;
protected Map<String,JarEntry> archiveEntries = null;
protected final Object archiveLock = new Object();
- private long archiveUseCount = 0;
- private JarContents jarContents;
- private boolean retainBloomFilterForArchives = false;
+ protected long archiveUseCount = 0;
+ protected JarContents jarContents;
+ protected boolean retainBloomFilterForArchives = false;
protected final void setBaseUrl(URL baseUrl) {
this.baseUrl = baseUrl;
diff --git a/java/org/apache/catalina/webresources/JarContents.java
b/java/org/apache/catalina/webresources/JarContents.java
index 58e0bff993..31438bd88d 100644
--- a/java/org/apache/catalina/webresources/JarContents.java
+++ b/java/org/apache/catalina/webresources/JarContents.java
@@ -17,6 +17,7 @@
package org.apache.catalina.webresources;
import java.util.BitSet;
+import java.util.Collection;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@@ -27,8 +28,7 @@ import java.util.jar.JarFile;
* from the beginning of the key. The hash methods are simple but good enough
for this purpose.
*/
public final class JarContents {
- private final BitSet bits1;
- private final BitSet bits2;
+
/**
* Constant used by a typical hashing method.
*/
@@ -44,6 +44,10 @@ public final class JarContents {
*/
private static final int TABLE_SIZE = 2048;
+ private final BitSet bits1 = new BitSet(TABLE_SIZE);
+ private final BitSet bits2 = new BitSet(TABLE_SIZE);
+
+
/**
* Parses the passed-in jar and populates the bit array.
*
@@ -51,52 +55,66 @@ public final class JarContents {
*/
public JarContents(JarFile jar) {
Enumeration<JarEntry> entries = jar.entries();
- bits1 = new BitSet(TABLE_SIZE);
- bits2 = new BitSet(TABLE_SIZE);
-
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
- String name = entry.getName();
- int startPos = 0;
-
- // If the path starts with a slash, that's not useful information.
- // Skipping it increases the significance of our key by
- // removing an insignificant character.
- boolean precedingSlash = name.charAt(0) == '/';
- if (precedingSlash) {
- startPos = 1;
- }
+ processEntry(entry);
+ }
+ }
- // Versioned entries should be added to the table according to
their real name
- if (name.startsWith("META-INF/versions/", startPos)) {
- int i = name.indexOf('/', 18 + startPos);
- if (i > 0) {
- int version = Integer.parseInt(name.substring(18 +
startPos, i));
- if (version <= Runtime.version().feature()) {
- startPos = i + 1;
- }
- }
- if (startPos == name.length()) {
- continue;
+
+ /**
+ * Populates the bit array from the provided set of JAR entries.
+ *
+ * @param entries The set of entries for the JAR file being processed
+ */
+ public JarContents(Collection<JarEntry> entries) {
+ for (JarEntry entry : entries) {
+ processEntry(entry);
+ }
+ }
+
+
+ private void processEntry(JarEntry entry) {
+ String name = entry.getName();
+ int startPos = 0;
+
+ // If the path starts with a slash, that's not useful information.
+ // Skipping it increases the significance of our key by
+ // removing an insignificant character.
+ boolean precedingSlash = name.charAt(0) == '/';
+ if (precedingSlash) {
+ startPos = 1;
+ }
+
+ // Versioned entries should be added to the table according to their
real name
+ if (name.startsWith("META-INF/versions/", startPos)) {
+ int i = name.indexOf('/', 18 + startPos);
+ if (i > 0) {
+ int version = Integer.parseInt(name.substring(18 + startPos,
i));
+ if (version <= Runtime.version().feature()) {
+ startPos = i + 1;
}
}
+ if (startPos == name.length()) {
+ return;
+ }
+ }
- // Find the correct table slot
- int pathHash1 = hashcode(name, startPos, HASH_PRIME_1);
- int pathHash2 = hashcode(name, startPos, HASH_PRIME_2);
+ // Find the correct table slot
+ int pathHash1 = hashcode(name, startPos, HASH_PRIME_1);
+ int pathHash2 = hashcode(name, startPos, HASH_PRIME_2);
- bits1.set(pathHash1 % TABLE_SIZE);
- bits2.set(pathHash2 % TABLE_SIZE);
+ bits1.set(pathHash1 % TABLE_SIZE);
+ bits2.set(pathHash2 % TABLE_SIZE);
- // While directory entry names always end in "/", application code
- // may look them up without the trailing "/". Add this second form.
- if (entry.isDirectory()) {
- pathHash1 = hashcode(name, startPos, name.length() - 1,
HASH_PRIME_1);
- pathHash2 = hashcode(name, startPos, name.length() - 1,
HASH_PRIME_2);
+ // While directory entry names always end in "/", application code
+ // may look them up without the trailing "/". Add this second form.
+ if (entry.isDirectory()) {
+ pathHash1 = hashcode(name, startPos, name.length() - 1,
HASH_PRIME_1);
+ pathHash2 = hashcode(name, startPos, name.length() - 1,
HASH_PRIME_2);
- bits1.set(pathHash1 % TABLE_SIZE);
- bits2.set(pathHash2 % TABLE_SIZE);
- }
+ bits1.set(pathHash1 % TABLE_SIZE);
+ bits2.set(pathHash2 % TABLE_SIZE);
}
}
diff --git a/java/org/apache/catalina/webresources/JarWarResourceSet.java
b/java/org/apache/catalina/webresources/JarWarResourceSet.java
index 54d980c0b4..cdc827fb05 100644
--- a/java/org/apache/catalina/webresources/JarWarResourceSet.java
+++ b/java/org/apache/catalina/webresources/JarWarResourceSet.java
@@ -28,6 +28,7 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;
+import java.util.zip.ZipFile;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.WebResource;
@@ -147,11 +148,34 @@ public class JarWarResourceSet extends
AbstractArchiveResourceSet {
}
}
}
+ WebResourceRoot root = getRoot();
+ if (root.getArchiveIndexStrategyEnum().getUsesBloom()) {
+ jarContents = new JarContents(archiveEntries.values());
+ retainBloomFilterForArchives =
root.getArchiveIndexStrategyEnum().getRetain();
+ }
return archiveEntries;
}
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * JarWar needs to generate jarContents for the inner JAR, not the outer
WAR.
+ */
+ @Override
+ protected JarFile openJarFile() throws IOException {
+ synchronized (archiveLock) {
+ if (archive == null) {
+ archive = new JarFile(new File(getBase()), true,
ZipFile.OPEN_READ, Runtime.version());
+ // Don't populate JarContents here. Populate at the end of
getArchiveEntries()
+ }
+ archiveUseCount++;
+ return archive;
+ }
+ }
+
+
protected void processArchivesEntriesForMultiRelease() {
int targetVersion = Runtime.version().feature();
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index f89e6b957c..92c92b0bdc 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -105,23 +105,14 @@
issues do not "pop up" wrt. others).
-->
<section name="Tomcat 10.1.44 (schultz)" rtext="in development">
- <subsection name="Coyote">
+ <subsection name="Catalina">
<changelog>
<fix>
- <bug>69748</bug>: Add missing call to set keep-alive timeout when using
- HTTP/1.1 following an async request, which was present for AJP.
- (remm/markt)
+ Fix bloom filter population for archive indexing when using a packed
+ WAR containing one or more JAR files. (markt)
</fix>
</changelog>
</subsection>
- <subsection name="Cluster">
- <changelog>
- <update>
- Add <code>enableStatistics</code> configuration attribute for the
- <code>DeltaManager</code>, defaulting to <code>true</code>. (remm)
- </update>
- </changelog>
- </subsection>
</section>
<section name="Tomcat 10.1.43 (schultz)" rtext="2025-07-04">
<subsection name="Catalina">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]