From fb2192afa92eecd761d9e25cdc5c7a8711e20a9e Mon Sep 17 00:00:00 2001 From: Dimitris Soumis Date: Tue, 9 Jun 2026 15:14:50 +0300 Subject: [PATCH] Make Cluster digester rules fully conditional on ha and tribes JARs The ObjectCreate rules for the 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 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 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 ec1c8818baf0..3ab65ae2d776 100644 --- a/java/org/apache/catalina/startup/Catalina.java +++ b/java/org/apache/catalina/startup/Catalina.java @@ -597,8 +597,15 @@ private void addClusterRuleSet(Digester digester, String prefix) { 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 e4ef9d9488f0..166160f730c2 100644 --- a/java/org/apache/catalina/startup/EngineRuleSet.java +++ b/java/org/apache/catalina/startup/EngineRuleSet.java @@ -64,13 +64,6 @@ public void addRuleInstances(Digester digester) { 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 6b21e49bbf4e..c11bce5f7706 100644 --- a/java/org/apache/catalina/startup/HostRuleSet.java +++ b/java/org/apache/catalina/startup/HostRuleSet.java @@ -67,13 +67,6 @@ public void addRuleInstances(Digester digester) { 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 aca96c0b7915..faa2121a925e 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -367,6 +367,14 @@ detailed error information (message, description, stack trace) is suppressed from error responses. (dsoumis) + + Avoid a NoClassDefFoundError at startup when + catalina-tribes.jar is removed but + catalina-ha.jar is present and the + Cluster element is enabled in + server.xml. Cluster digester rules are now fully + conditional on both JARs being available. (dsoumis) +