[jira] [Resolved] (AXIS2-5904) Intermittent Rampart policy configuration missing Error

"Robert Lazarski (Jira)" <[email protected]> Sun, 17 May 2026 22:03:00 +0000 (UTC)
Newsgroups gmane.text.xml.axis.devel
Message-ID <[email protected]>
     [ https://issues.apache.org/jira/browse/AXIS2-5904?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Robert Lazarski resolved AXIS2-5904.
------------------------------------
    Fix Version/s: 2.0.1
       Resolution: Fixed

  Fixed in commits 118dcca, 18fd259, a4f18f6, efa70b7 on master (will ship
  in 2.0.1).

  Root cause: AxisBindingMessage.getEffectivePolicy() and
  AxisMessage.getEffectivePolicy() used Date.after() to detect policy
  changes in the description hierarchy. java.util.Date has millisecond
  granularity — two policy updates within the same millisecond produced
  identical timestamps, causing isPolicyUpdated() to return false and the
  cached (potentially null) effective policy to be returned. This
  manifested as intermittent "Rampart policy configuration missing" errors
  on consecutive secured SOAP calls, as Andreas Veithen diagnosed in Jan
  2018.

  Fix: Replaced Date-based timestamp comparison with a monotonic AtomicLong
   counter in PolicySubject. Every policy mutation (attach, detach, update,
   clear) increments a global counter. isPolicyUpdated() now compares
  version numbers instead of timestamps — guaranteed unique, strictly
  increasing, zero granularity issues. The fix applies to both
  AxisBindingMessage and AxisMessage, which are the two classes in the
  hierarchy that cache effective policies. The deprecated Date-based
  getLastUpdatedTime()/setLastUpdatedTime() API is preserved in
  PolicySubject for backward compatibility.

  Tests: Added PolicyCacheRaceTest (5 tests) covering version monotonicity
  on attach/detach/clear, effective policy detection after update, and a
  rapid-fire 100-iteration scenario simulating the same-millisecond race.
  Full kernel test suite (402 tests) passes.

  Note for Rampart 2.0.0: This fix is in axis2-kernel which Rampart depends
   on. The upcoming Rampart 2.0.0 release (based on Axis2 2.0.1) will
  inherit this fix automatically.


> Intermittent Rampart policy configuration missing Error
> -------------------------------------------------------
>
>                 Key: AXIS2-5904
>                 URL: https://issues.apache.org/jira/browse/AXIS2-5904
>             Project: Axis2
>          Issue Type: Bug
>          Components: client-api, codegen, modules, rpc
>    Affects Versions: 1.7.0, 1.7.7
>         Environment: Apache Tomcat 9
>            Reporter: Mohamed Anis Mekki
>            Priority: Critical
>             Fix For: 2.0.1
>
>
> I created a secured (sign body) Axis2 Web Service and generated .aar archive which I deployed to Axis2 Container (.war in Apache Tomcat). I then used Java2WSDL to generate a client stub. I finally created the class below that uses the client stub.
> In a nutshell the main method of the class calls consecutively the first then the second method of the service. I create a separate service stub for each call, using serviceStub() method and configure correctly the rampart security policy using getRampartConfig() method.
> {code:java}
> package tn.nat.cnss.client;
> import java.util.Properties;
> import java.rmi.RemoteException;
> import org.apache.axis2.AxisFault;
> import org.apache.axis2.context.ConfigurationContext;
> import org.apache.axis2.context.ConfigurationContextFactory;
> import org.apache.axis2.transport.http.HTTPConstants;
> import org.apache.neethi.Policy;
> import org.apache.rampart.policy.model.CryptoConfig;
> import org.apache.rampart.policy.model.RampartConfig;
> import tn.nat.cnss.client.Sample2SignBodyServiceStub.ArrayOfString;
> import tn.nat.cnss.client.Sample2SignBodyServiceStub.Operation1;
> import tn.nat.cnss.client.Sample2SignBodyServiceStub.Operation2;
> import tn.nat.cnss.client.Sample2SignBodyServiceStub.Operation1Response;
> import tn.nat.cnss.client.Sample2SignBodyServiceStub.Operation2Response;
> import tn.nat.cnss.client.Sample2SignBodyServiceStub.ServiceRequestOperation1;
> import tn.nat.cnss.client.Sample2SignBodyServiceStub.ServiceRequestOperation2;
> public class Sample2SignBodyServiceClient
> {
> 	private static Policy getRampartConfig()
> 	{
> 		RampartConfig rampartConfig = new RampartConfig();
> 		rampartConfig.setUser("clientkey");
> 		rampartConfig.setPwCbClass("tn.nat.cnss.client.PasswordCallBackHandler");
> 		CryptoConfig sigCrypto = new CryptoConfig();
> 		sigCrypto.setProvider("org.apache.ws.security.components.crypto.Merlin");
> 		Properties props = new Properties();
> 		props.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", "JKS");
> 		props.setProperty("org.apache.ws.security.crypto.merlin.file","keys/client.jks");
> 		props.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", "clientStorePW");
> 		sigCrypto.setProp(props);
> 		rampartConfig.setSigCryptoConfig(sigCrypto);
> 		Policy policy = new Policy();
> 		policy.addAssertion(rampartConfig);
> 		return policy;  
> 	}
> 	private static Sample2SignBodyServiceStub serviceStub() throws AxisFault
> 	{
> 		org.apache.log4j.Logger.getRootLogger().setLevel(org.apache.log4j.Level.OFF);
> 		ConfigurationContext ctx = ConfigurationContextFactory.createConfigurationContextFromFileSystem("client-repo", null);
> 		Sample2SignBodyServiceStub serviceStub = new Sample2SignBodyServiceStub(ctx,"http://localhost:8080/axis2/services/Sample2SignBodyService");
> 		serviceStub._getServiceClient().engageModule("rampart");
> 		Policy rampartConfig = getRampartConfig();
> 		serviceStub._getServiceClient().getAxisService().getPolicySubject().attachPolicy(rampartConfig);
> 		serviceStub._getServiceClient().getOptions().setTimeOutInMilliSeconds(300000);
> 		serviceStub._getServiceClient().getOptions().setProperty(HTTPConstants.SO_TIMEOUT, new Integer(300000));
> 		serviceStub._getServiceClient().getOptions().setProperty(HTTPConstants.CONNECTION_TIMEOUT, new Integer(300000));
> 		return serviceStub;
> 	}
> 	public static Operation1Response operation1(String...parameters) throws RemoteException, AxisFault
> 	{
> 		Sample2SignBodyServiceStub serviceStub = serviceStub();
> 		ServiceRequestOperation1 req = new ServiceRequestOperation1();
> 		req.setParam1(parameters[0]);
> 		req.setParam2(parameters[1]);
> 		req.setParam3(parameters[2]);
> 		Operation1 operation = new Operation1();
> 		operation.setServiceRequestOperation1(req);
> 		Operation1Response resp = serviceStub.operation1(operation);
> 		serviceStub._getServiceClient().cleanupTransport();
> 		serviceStub._getServiceClient().cleanup();
> 		serviceStub.cleanup();
> 		return resp;
> 	}
> 	public static Operation2Response operation2(String...parameters) throws RemoteException, AxisFault
> 	{
> 		Sample2SignBodyServiceStub serviceStub = serviceStub();
> 		ServiceRequestOperation2 req = new ServiceRequestOperation2();
> 		req.setParam1(parameters[0]);
> 		req.setParam2(parameters[1]);
> 		Operation2 operation = new Operation2();
> 		operation.setServiceRequestOperation2(req);
> 		Operation2Response resp = serviceStub.operation2(operation);
> 		serviceStub._getServiceClient().cleanupTransport();
> 		serviceStub._getServiceClient().cleanup();
> 		serviceStub.cleanup();
> 		return resp;
> 	}
> 	public static void main(String[] args) throws Exception
> 	{   
> 		Operation1Response operation1Response = operation1("0", "99999", "99999");
> 		System.out.println("operation1: Debut Execution");
> 		System.out.println(operation1Response.get_return().getResult());
> 		System.out.println("Nombre de colonnes: " + operation1Response.get_return().getNumberColumns());
> 		System.out.println("Nombre de lignes: " + operation1Response.get_return().getNumberLines());
> 		for (ArrayOfString array : operation1Response.get_return().getDataSet())
> 		{
> 			for (String s : array.localArray)
> 			{
> 				System.out.print(s + "\t");
> 			}
> 			System.out.println();
> 		}
> 		System.out.println("operation1: Fin Execution");
> 		Operation2Response operation2Response = operation2("0", "99999");
> 		System.out.println("operation2: Debut Execution");
> 		System.out.println(operation2Response.get_return().getResult());
> 		System.out.println("Nombre de colonnes: " + operation2Response.get_return().getNumberColumns());
> 		System.out.println("Nombre de lignes: " + operation2Response.get_return().getNumberLines());
> 		for (ArrayOfString array : operation2Response.get_return().getDataSet())
> 		{
> 			for (String s : array.localArray)
> 			{
> 				System.out.print(s + "\t");
> 			}
> 			System.out.println();
> 		}
> 		System.out.println("operation2: Fin Execution");
> 	}
> }
> {code}
> The problem is that execution leads to the intermittent error below. By intermittent I mean that sometimes both operation calls execute properly, but some other times only the first call or none.
> {code:java}
> org.apache.axis2.AxisFault: Rampart policy configuration missing
>     at org.apache.rampart.handler.RampartSender.invoke(RampartSender.java:76)
>     at org.apache.axis2.engine.Phase.invokeHandler(Phase.java:335)
>     at org.apache.axis2.engine.Phase.invoke(Phase.java:308)
>     at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:250)
>     at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:415)
>     at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:399)
>     at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:225)
>     at org.apache.axis2.client.OperationClient.execute(OperationClient.java:150)
>     at tn.nat.cnss.client.Sample4SignEncryptBodyServiceSSLStub.operation2(Sample4SignEncryptBodyServiceSSLStub.java:307)
>     at tn.nat.cnss.client.Sample4SignEncryptBodyServiceSSLClient.operation2(Sample4SignEncryptBodyServiceSSLClient.java:121)
>     at tn.nat.cnss.client.Sample4SignEncryptBodyServiceSSLClient.main(Sample4SignEncryptBodyServiceSSLClient.java:162)
> Caused by: org.apache.rampart.RampartException: Rampart policy configuration missing
>     at org.apache.rampart.builder.BindingBuilder.getSignatureBuilder(BindingBuilder.java:277)
>     at org.apache.rampart.builder.BindingBuilder.getSignatureBuilder(BindingBuilder.java:250)
>     at org.apache.rampart.builder.AsymmetricBindingBuilder.doSignature(AsymmetricBindingBuilder.java:760)
>     at org.apache.rampart.builder.AsymmetricBindingBuilder.doSignBeforeEncrypt(AsymmetricBindingBuilder.java:417)
>     at org.apache.rampart.builder.AsymmetricBindingBuilder.build(AsymmetricBindingBuilder.java:88)
>     at org.apache.rampart.MessageBuilder.build(MessageBuilder.java:147)
>     at org.apache.rampart.handler.RampartSender.invoke(RampartSender.java:65)
>     ... 10 more
> {code}
> I use Axis2 version 1.7.0 and Apache Tomcat 9.0 with Java 8.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)