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

robertlazarski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/axis-axis2-java-rampart.git

commit 37dd4b399616826c54d85597c11d8953e5582eba
Author: Robert Lazarski <[email protected]>
AuthorDate: Thu Oct 8 18:14:51 2026 -1000

    Fail rampart and rahas module init clearly when guava is missing
    
    A hand-assembled classpath without guava used to surface as a
    NoClassDefFoundError deep in OpenSAML. Both modules now check at init and 
log
    an ERROR naming the jars to copy, since Axis2 logs module init faults at 
INFO.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../src/main/java/org/apache/rampart/Rampart.java  |  3 +++
 .../src/main/java/org/apache/rahas/Rahas.java      |  3 +++
 .../rahas/impl/util/OpenSAMLInitializer.java       | 27 ++++++++++++++++++++++
 .../rahas/impl/util/OpenSAMLInitializerTest.java   | 19 +++++++++++++++
 src/site/markdown/release-notes/2.0.0.md           | 10 ++++++++
 5 files changed, 62 insertions(+)

diff --git a/modules/rampart-core/src/main/java/org/apache/rampart/Rampart.java 
b/modules/rampart-core/src/main/java/org/apache/rampart/Rampart.java
index 72f23164..750a1433 100644
--- a/modules/rampart-core/src/main/java/org/apache/rampart/Rampart.java
+++ b/modules/rampart-core/src/main/java/org/apache/rampart/Rampart.java
@@ -23,6 +23,7 @@ import org.apache.axis2.description.AxisModule;
 import org.apache.axis2.modules.Module;
 import org.apache.neethi.Assertion;
 import org.apache.neethi.Policy;
+import org.apache.rahas.impl.util.OpenSAMLInitializer;
 import org.apache.rampart.policy.model.RampartConfig;
 import org.apache.ws.secpolicy.SP11Constants;
 import org.apache.ws.secpolicy.SP12Constants;
@@ -31,6 +32,8 @@ public class Rampart implements Module /* , 
ModulePolicyExtension */  {
 
     public void init(ConfigurationContext configContext, AxisModule module)
             throws AxisFault {
+        // OpenSAML is used on the message path, so check its runtime 
dependencies here.
+        OpenSAMLInitializer.checkRuntimeDependencies();
     }
 
     public void engageNotify(AxisDescription axisDescription) throws AxisFault 
{
diff --git a/modules/rampart-trust/src/main/java/org/apache/rahas/Rahas.java 
b/modules/rampart-trust/src/main/java/org/apache/rahas/Rahas.java
index 2cdd416f..0e0054bc 100644
--- a/modules/rampart-trust/src/main/java/org/apache/rahas/Rahas.java
+++ b/modules/rampart-trust/src/main/java/org/apache/rahas/Rahas.java
@@ -25,6 +25,7 @@ import org.apache.axis2.description.AxisModule;
 import org.apache.axis2.modules.Module;
 import org.apache.neethi.Assertion;
 import org.apache.neethi.Policy;
+import org.apache.rahas.impl.util.OpenSAMLInitializer;
 import org.apache.ws.secpolicy.SP11Constants;
 import org.apache.ws.secpolicy.SP12Constants;
 import org.opensaml.core.config.InitializationException;
@@ -36,6 +37,8 @@ public class Rahas implements Module {
         // Set up OpenSAML to use a DOM aware Axiom implementation
         // Axiom Parser pool is also set within the RampartSAMLBootstrap class.
 
+        OpenSAMLInitializer.checkRuntimeDependencies();
+
         try {
             RampartSAMLBootstrap.initialize();
 
diff --git 
a/modules/rampart-trust/src/main/java/org/apache/rahas/impl/util/OpenSAMLInitializer.java
 
b/modules/rampart-trust/src/main/java/org/apache/rahas/impl/util/OpenSAMLInitializer.java
index 2b30ed79..50a504d9 100644
--- 
a/modules/rampart-trust/src/main/java/org/apache/rahas/impl/util/OpenSAMLInitializer.java
+++ 
b/modules/rampart-trust/src/main/java/org/apache/rahas/impl/util/OpenSAMLInitializer.java
@@ -18,6 +18,7 @@
  */
 package org.apache.rahas.impl.util;
 
+import org.apache.axis2.AxisFault;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.wss4j.common.saml.OpenSAMLUtil;
@@ -50,6 +51,32 @@ public final class OpenSAMLInitializer {
     private OpenSAMLInitializer() {
     }
 
+    /**
+     * Fails module initialisation with a clear message when guava is missing.
+     *
+     * <p>OpenSAML, Shibboleth and WSS4J all need guava at runtime. Axis2 
2.0.2 stopped
+     * bundling it, so it now ships in the Rampart distribution's lib/; an 
installation
+     * assembled by hand can easily miss it. Without this check the failure 
surfaces as
+     * a NoClassDefFoundError deep inside OpenSAML, and Axis2 logs module init 
faults
+     * only at INFO, so the reason is logged here at ERROR as well.</p>
+     */
+    public static void checkRuntimeDependencies() throws AxisFault {
+        checkRuntimeDependencies(InitializationService.class.getClassLoader());
+    }
+
+    static void checkRuntimeDependencies(ClassLoader openSAMLLoader) throws 
AxisFault {
+        try {
+            Class.forName("com.google.common.base.Strings", false, 
openSAMLLoader);
+        } catch (ClassNotFoundException | LinkageError e) {
+            String message = "Google Guava is not on the classpath, but 
OpenSAML and WSS4J"
+                    + " require it. Copy the guava and failureaccess jars from 
the Rampart"
+                    + " distribution's lib/ directory into the Axis2 lib/ (or 
WEB-INF/lib)"
+                    + " directory alongside the other Rampart dependencies.";
+            log.error(message);
+            throw new AxisFault(message, e);
+        }
+    }
+
     /**
      * Initialises OpenSAML once. After the first successful call this is a 
single
      * volatile read. A failed attempt is not recorded, so the next call 
retries.
diff --git 
a/modules/rampart-trust/src/test/java/org/apache/rahas/impl/util/OpenSAMLInitializerTest.java
 
b/modules/rampart-trust/src/test/java/org/apache/rahas/impl/util/OpenSAMLInitializerTest.java
index 7ae2e12c..d47adcc1 100644
--- 
a/modules/rampart-trust/src/test/java/org/apache/rahas/impl/util/OpenSAMLInitializerTest.java
+++ 
b/modules/rampart-trust/src/test/java/org/apache/rahas/impl/util/OpenSAMLInitializerTest.java
@@ -18,12 +18,16 @@
  */
 package org.apache.rahas.impl.util;
 
+import java.net.URL;
+import java.net.URLClassLoader;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CountDownLatch;
 
 import junit.framework.TestCase;
 
+import org.apache.axis2.AxisFault;
+
 import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
 import org.opensaml.xmlsec.SecurityConfigurationSupport;
 import org.opensaml.xmlsec.SignatureSigningConfiguration;
@@ -61,6 +65,21 @@ public class OpenSAMLInitializerTest extends TestCase {
                 
SecurityConfigurationSupport.getGlobalSignatureSigningConfiguration());
     }
 
+    public void testRuntimeDependencyCheckPassesWithGuava() throws Exception {
+        OpenSAMLInitializer.checkRuntimeDependencies();
+    }
+
+    /** A missing guava must fail module init with a message naming the jars 
to add. */
+    public void testRuntimeDependencyCheckFailsWithoutGuava() throws Exception 
{
+        ClassLoader withoutGuava = new URLClassLoader(new URL[0], null);
+        try {
+            OpenSAMLInitializer.checkRuntimeDependencies(withoutGuava);
+            fail("a classpath without guava must fail the check");
+        } catch (AxisFault expected) {
+            assertTrue(expected.getMessage(), 
expected.getMessage().contains("guava"));
+        }
+    }
+
     public void testConcurrentCallsSucceed() throws Exception {
         final int threadCount = 16;
         final CountDownLatch startGate = new CountDownLatch(1);
diff --git a/src/site/markdown/release-notes/2.0.0.md 
b/src/site/markdown/release-notes/2.0.0.md
index 206b3f61..7f102c2e 100644
--- a/src/site/markdown/release-notes/2.0.0.md
+++ b/src/site/markdown/release-notes/2.0.0.md
@@ -12,6 +12,16 @@ Axis2.
 - **Java**: OpenJDK 17 minimum; tested on OpenJDK 17, 21, and 25.
 - **Apache Axis2**: 2.0.1 (Jakarta-based).
 
+## Installation Note: Guava
+
+OpenSAML and WSS4J require Google Guava at runtime. Axis2 2.0.2 no longer 
bundles
+it, so the Rampart binary distribution now ships `guava`, `failureaccess` and
+`jspecify` in its `lib/` directory, and `ant` copies them into Axis2 with the 
other
+Rampart dependencies. Guava is pinned to the version Axis2 2.0.1 shipped, so
+installing into 2.0.1 replaces that jar rather than adding a second copy. If 
you
+assemble `WEB-INF/lib` by hand, include these jars: without them the rampart 
and
+rahas modules now fail to initialise with an error naming the missing jars.
+
 ## Current Dependency Versions
 
 This release uses the following updated dependency versions:

Reply via email to