diff --git a/rhbz-1857043.patch b/rhbz-1857043.patch index 862675b..055d918 100644 --- a/rhbz-1857043.patch +++ b/rhbz-1857043.patch @@ -6,7 +6,7 @@ manifest="${tomcat.manifests}/annotations-api.jar.manifest" - addOSGi="true" /> + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + @@ -1258,7 +1258,7 @@ @@ -123,7 +123,7 @@ filesId="files.catalina" - addOSGi="true" /> + addOSGi="false" /> - + @@ -1279,7 +1279,7 @@ @@ -132,7 +132,7 @@ filesId="files.catalina-ssi" - addOSGi="true" /> + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + + addOSGi="false" /> - + clusterValveClass; -- static { -- Class clazz = null; -- try { -- clazz = Class.forName("org.apache.catalina.ha.ClusterValve"); -- } catch (ClassNotFoundException e) { -- // Expected when clustering JARs are not present -- } -- clusterValveClass = clazz; -- } -- - /** - * Store the specified Engine properties. - *

-@@ -74,7 +64,7 @@ - if (valves != null && valves.length > 0) { - List engineValves = new ArrayList<>(); - for (Valve valve : valves) { -- if (clusterValveClass == null || !clusterValveClass.isInstance(valve)) { -+ if (!(valve instanceof ClusterValve)) { - engineValves.add(valve); - } - } -diff --git a/java/org/apache/catalina/storeconfig/StandardHostSF.java b/java/org/apache/catalina/storeconfig/StandardHostSF.java -index 60d473982b..1e8f2d3a58 100644 ---- a/java/org/apache/catalina/storeconfig/StandardHostSF.java -+++ b/java/org/apache/catalina/storeconfig/StandardHostSF.java -@@ -26,23 +26,13 @@ - import org.apache.catalina.Realm; - import org.apache.catalina.Valve; - import org.apache.catalina.core.StandardHost; -+import org.apache.catalina.ha.ClusterValve; - - /** - * Store server.xml Element Host - */ - public class StandardHostSF extends StoreFactoryBase { - -- private static final Class clusterValveClass; -- static { -- Class clazz = null; -- try { -- clazz = Class.forName("org.apache.catalina.ha.ClusterValve"); -- } catch (ClassNotFoundException e) { -- // Expected when clustering JARs are not present -- } -- clusterValveClass = clazz; -- } -- - /** - * Store the specified Host properties and children (Listener,Alias,Realm,Valve,Cluster, Context) - *

-@@ -78,7 +68,7 @@ - if (valves != null && valves.length > 0) { - List hostValves = new ArrayList<>(); - for (Valve valve : valves) { -- if (clusterValveClass == null || !clusterValveClass.isInstance(valve)) { -+ if (!(valve instanceof ClusterValve)) { - hostValves.add(valve); - } - } -diff --git a/java/org/apache/catalina/storeconfig/StoreRegistry.java b/java/org/apache/catalina/storeconfig/StoreRegistry.java -index c17dd3817e..ee803abe36 100644 ---- a/java/org/apache/catalina/storeconfig/StoreRegistry.java -+++ b/java/org/apache/catalina/storeconfig/StoreRegistry.java -@@ -16,9 +16,7 @@ - */ - package org.apache.catalina.storeconfig; - --import java.util.ArrayList; - import java.util.HashMap; --import java.util.List; - import java.util.Map; - - import javax.naming.directory.DirContext; -@@ -30,6 +28,17 @@ - import org.apache.catalina.Valve; - import org.apache.catalina.WebResourceRoot; - import org.apache.catalina.WebResourceSet; -+import org.apache.catalina.ha.CatalinaCluster; -+import org.apache.catalina.ha.ClusterDeployer; -+import org.apache.catalina.ha.ClusterListener; -+import org.apache.catalina.tribes.Channel; -+import org.apache.catalina.tribes.ChannelInterceptor; -+import org.apache.catalina.tribes.ChannelReceiver; -+import org.apache.catalina.tribes.ChannelSender; -+import org.apache.catalina.tribes.Member; -+import org.apache.catalina.tribes.MembershipService; -+import org.apache.catalina.tribes.MessageListener; -+import org.apache.catalina.tribes.transport.DataSender; - import org.apache.coyote.UpgradeProtocol; - import org.apache.juli.logging.Log; - import org.apache.juli.logging.LogFactory; -@@ -52,74 +61,11 @@ - private String version; - - // Access Information -- // Lazily initialized to gracefully handle optional features like clustering -- private static volatile Class[] interfaces = null; -- -- /** -- * Initialize the interfaces array with all available classes. -- * Uses dynamic loading for optional classes (e.g., clustering) to avoid -- * ClassNotFoundException when those JARs are not present. This approach -- * is consistent with how Catalina.addClusterRuleSet() handles clustering. -- */ -- private static Class[] getInterfaces() { -- if (interfaces == null) { -- synchronized (StoreRegistry.class) { -- if (interfaces == null) { -- // Required interfaces - always present -- List> list = new ArrayList<>(); -- list.add(Realm.class); -- list.add(Manager.class); -- list.add(DirContext.class); -- list.add(LifecycleListener.class); -- list.add(Valve.class); -- list.add(WebResourceRoot.class); -- list.add(WebResourceSet.class); -- list.add(CredentialHandler.class); -- list.add(UpgradeProtocol.class); -- list.add(CookieProcessor.class); -- -- // Optional clustering interfaces - load dynamically to support -- // deployments where clustering JARs may not be present -- tryAddClass(list, "org.apache.catalina.ha.CatalinaCluster"); -- tryAddClass(list, "org.apache.catalina.tribes.ChannelSender"); -- tryAddClass(list, "org.apache.catalina.tribes.ChannelReceiver"); -- tryAddClass(list, "org.apache.catalina.tribes.Channel"); -- tryAddClass(list, "org.apache.catalina.tribes.MembershipService"); -- tryAddClass(list, "org.apache.catalina.ha.ClusterDeployer"); -- tryAddClass(list, "org.apache.catalina.ha.ClusterListener"); -- tryAddClass(list, "org.apache.catalina.tribes.MessageListener"); -- tryAddClass(list, "org.apache.catalina.tribes.transport.DataSender"); -- tryAddClass(list, "org.apache.catalina.tribes.ChannelInterceptor"); -- tryAddClass(list, "org.apache.catalina.tribes.Member"); -- -- interfaces = list.toArray(new Class[0]); -- -- if (log.isDebugEnabled()) { -- log.debug(sm.getString("registry.interfacesLoaded", Integer.valueOf(interfaces.length))); -- } -- } -- } -- } -- return interfaces; -- } -- -- /** -- * Try to load a class by name and add it to the list if successful. -- * Logs at TRACE level if the class is not available. -- */ -- private static void tryAddClass(List> list, String className) { -- try { -- Class clazz = Class.forName(className, false, StoreRegistry.class.getClassLoader()); -- list.add(clazz); -- if (log.isTraceEnabled()) { -- log.trace(sm.getString("registry.optionalClassLoaded", className)); -- } -- } catch (ClassNotFoundException | NoClassDefFoundError e) { -- if (log.isTraceEnabled()) { -- log.trace(sm.getString("registry.optionalClassNotFound", className)); -- } -- } -- } -+ private static final Class[] interfaces = { CatalinaCluster.class, ChannelSender.class, ChannelReceiver.class, -+ Channel.class, MembershipService.class, ClusterDeployer.class, Realm.class, Manager.class, DirContext.class, -+ LifecycleListener.class, Valve.class, ClusterListener.class, MessageListener.class, DataSender.class, -+ ChannelInterceptor.class, Member.class, WebResourceRoot.class, WebResourceSet.class, -+ CredentialHandler.class, UpgradeProtocol.class, CookieProcessor.class }; - - /** - * @return the name -@@ -170,10 +116,9 @@ - } - if (aClass != null) { - desc = descriptors.get(aClass.getName()); -- Class[] availableInterfaces = getInterfaces(); -- for (int i = 0; desc == null && i < availableInterfaces.length; i++) { -- if (availableInterfaces[i].isAssignableFrom(aClass)) { -- desc = descriptors.get(availableInterfaces[i].getName()); -+ for (int i = 0; desc == null && i < interfaces.length; i++) { -+ if (interfaces[i].isAssignableFrom(aClass)) { -+ desc = descriptors.get(interfaces[i].getName()); - } - } - } -diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml -index 012b607f18..17f639d669 100644 ---- a/webapps/docs/changelog.xml -+++ b/webapps/docs/changelog.xml -@@ -2830,6 +2830,13 @@ - The rewrite valve should not do a rewrite if the output is identical - to the input. (remm) - -+ -+ Update StoreRegistry to dynamically load optional clustering -+ classes rather than statically referencing them. This matches the pattern -+ used in Catalina.addClusterRuleSet() and prevents -+ NoClassDefFoundError when StoreConfigLifecycleListener -+ is configured but clustering classes are not available. (csutherl) -+ - - Add a new valveSkip (or VS) rule flag to the - rewrite valve to allow skipping over the next valve in the Catalina - diff --git a/tomcat.spec b/tomcat.spec index 2b14df9..41177bc 100644 --- a/tomcat.spec +++ b/tomcat.spec @@ -54,7 +54,7 @@ Name: tomcat Epoch: 1 Version: %{major_version}.%{minor_version}.%{micro_version} -Release: 2%{?dist} +Release: 3%{?dist} Summary: Apache Servlet/JSP Engine, RI for Servlet %{servletspec}/JSP %{jspspec} API License: Apache-2.0 @@ -81,7 +81,6 @@ Patch5: %{name}-%{major_version}.%{minor_version}-JDTCompiler.patch Patch6: rhbz-1857043.patch # Patch 7 can be dropped when ECJ is updated to a newer version Patch7: build-with-java-25.patch -patch8: rhel-168577.patch BuildArch: noarch ExclusiveArch: %{java_arches} noarch @@ -209,7 +208,6 @@ find . -type f \( -name "*.bat" -o -name "*.class" -o -name Thumbs.db -o -name " %patch 5 -p0 %patch 6 -p0 %patch 7 -p0 -%patch 8 -p1 # Remove webservices naming resources as it's generally unused %{__rm} -rf java/org/apache/naming/factory/webservices @@ -557,6 +555,9 @@ exit 0 %{appdir}/ROOT %changelog +* Mon Jul 6 2026 Pietro Meloni - 1:10.1.49-3 +- Related: RHEL-168577 Remove unnecessary patch + * Thu Jun 4 2026 Pietro Meloni - 1:10.1.49-2 - Resolves: RHEL-168577 Remove tomcat clustering JAR from RPM builds Resolves: CVE-2026-29146