This is an automated email from the ASF dual-hosted git repository.

dsoumis pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
     new fc8c6c9147 Make Cluster digester rules fully conditional on ha and 
tribes JARs
fc8c6c9147 is described below

commit fc8c6c91478b9bcf50d72649b7083e1d12aadee9
Author: Dimitris Soumis <[email protected]>
AuthorDate: Tue Jun 9 15:14:50 2026 +0300

    Make Cluster digester rules fully conditional on ha and tribes JARs
    
      The ObjectCreate rules for the <Cluster> element were registered
      unconditionally in EngineRuleSet and HostRuleSet, while the child
      element rules in ClusterRuleSet were already guarded behind a
      try/catch in Catalina.addClusterRuleSet(). This caused a
      NoClassDefFoundError crash when catalina-tribes.jar was removed
      but catalina-ha.jar was present and <Cluster> was enabled in
      server.xml.
    
      Move the Cluster element rules into addClusterRuleSet() alongside
      the child element rules, and add a probe for tribes availability.
      Either both JARs are present and clustering works, or the <Cluster>
      element is ignored with an INFO log.
---
 java/org/apache/catalina/startup/Catalina.java      | 7 +++++++
 java/org/apache/catalina/startup/EngineRuleSet.java | 7 -------
 java/org/apache/catalina/startup/HostRuleSet.java   | 7 -------
 webapps/docs/changelog.xml                          | 8 ++++++++
 4 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/java/org/apache/catalina/startup/Catalina.java 
b/java/org/apache/catalina/startup/Catalina.java
index 479da5fed8..fda29aa857 100644
--- a/java/org/apache/catalina/startup/Catalina.java
+++ b/java/org/apache/catalina/startup/Catalina.java
@@ -573,8 +573,15 @@ public class Catalina {
         Constructor<?> constructor;
         try {
             clazz = Class.forName("org.apache.catalina.ha.ClusterRuleSet");
+            Class.forName("org.apache.catalina.tribes.Channel");
             constructor = clazz.getConstructor(String.class);
             RuleSet ruleSet = (RuleSet) constructor.newInstance(prefix);
+
+            String clusterPrefix = prefix.substring(0, prefix.length() - 1);
+            digester.addObjectCreate(clusterPrefix, null, "className");
+            digester.addSetProperties(clusterPrefix);
+            digester.addSetNext(clusterPrefix, "setCluster", 
"org.apache.catalina.Cluster");
+
             digester.addRuleSet(ruleSet);
         } catch (Exception e) {
             if (!clusterUnavailabilityLogged) {
diff --git a/java/org/apache/catalina/startup/EngineRuleSet.java 
b/java/org/apache/catalina/startup/EngineRuleSet.java
index 1e60b5b1e9..63758bb821 100644
--- a/java/org/apache/catalina/startup/EngineRuleSet.java
+++ b/java/org/apache/catalina/startup/EngineRuleSet.java
@@ -64,13 +64,6 @@ public class EngineRuleSet implements RuleSet {
                 new 
LifecycleListenerRule("org.apache.catalina.startup.EngineConfig", 
"engineConfigClass"));
         digester.addSetNext(prefix + "Engine", "setContainer", 
"org.apache.catalina.Engine");
 
-        // Cluster configuration start
-        digester.addObjectCreate(prefix + "Engine/Cluster", null, // MUST be 
specified in the element
-                "className");
-        digester.addSetProperties(prefix + "Engine/Cluster");
-        digester.addSetNext(prefix + "Engine/Cluster", "setCluster", 
"org.apache.catalina.Cluster");
-        // Cluster configuration end
-
         digester.addObjectCreate(prefix + "Engine/Listener", null, // MUST be 
specified in the element
                 "className");
         digester.addSetProperties(prefix + "Engine/Listener");
diff --git a/java/org/apache/catalina/startup/HostRuleSet.java 
b/java/org/apache/catalina/startup/HostRuleSet.java
index 4454a61361..2d6b04236c 100644
--- a/java/org/apache/catalina/startup/HostRuleSet.java
+++ b/java/org/apache/catalina/startup/HostRuleSet.java
@@ -67,13 +67,6 @@ public class HostRuleSet implements RuleSet {
 
         digester.addCallMethod(prefix + "Host/Alias", "addAlias", 0);
 
-        // Cluster configuration start
-        digester.addObjectCreate(prefix + "Host/Cluster", null, // MUST be 
specified in the element
-                "className");
-        digester.addSetProperties(prefix + "Host/Cluster");
-        digester.addSetNext(prefix + "Host/Cluster", "setCluster", 
"org.apache.catalina.Cluster");
-        // Cluster configuration end
-
         digester.addObjectCreate(prefix + "Host/Listener", null, // MUST be 
specified in the element
                 "className");
         digester.addSetProperties(prefix + "Host/Listener");
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 355530e500..edae2511d4 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -256,6 +256,14 @@
         detailed error information (message, description, stack trace) is
         suppressed from error responses. (dsoumis)
       </add>
+      <fix>
+        Avoid a <code>NoClassDefFoundError</code> at startup when
+        <code>catalina-tribes.jar</code> is removed but
+        <code>catalina-ha.jar</code> is present and the
+        <code>Cluster</code> element is enabled in
+        <code>server.xml</code>. Cluster digester rules are now fully
+        conditional on both JARs being available. (dsoumis)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to