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-core.git

commit 18fd259c55d6dd006178b6c98e79a7312160acc4
Author: Robert Lazarski <[email protected]>
AuthorDate: Sun May 17 11:53:10 2026 -1000

    AXIS2-5904 Fix same race condition in AxisMessage.isPolicyUpdated()
    
    AxisMessage has the identical Date.after() millisecond-granularity
    race as AxisBindingMessage (fixed in prior commit). Apply the same
    AtomicLong version counter fix. Both classes in the policy hierarchy
    that cache effective policies are now using monotonic counters.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---
 .../org/apache/axis2/description/AxisMessage.java  | 40 ++++++++++++----------
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/modules/kernel/src/org/apache/axis2/description/AxisMessage.java 
b/modules/kernel/src/org/apache/axis2/description/AxisMessage.java
index f7a1d072a1..6f6fb88f65 100644
--- a/modules/kernel/src/org/apache/axis2/description/AxisMessage.java
+++ b/modules/kernel/src/org/apache/axis2/description/AxisMessage.java
@@ -68,6 +68,7 @@ public class AxisMessage extends AxisDescription {
 
     private volatile Policy effectivePolicy = null;
     private volatile Date lastPolicyCalculatedTime = null;
+    private volatile long lastPolicyCalculatedVersion = -1;
 
     public String getMessagePartName() {
         return messagePartName;
@@ -237,11 +238,12 @@ public class AxisMessage extends AxisDescription {
     }
 
     public Policy getEffectivePolicy() {
-        if (lastPolicyCalculatedTime == null || isPolicyUpdated()) {
+        if (isPolicyUpdated()) {
             synchronized (this) {
-                if (lastPolicyCalculatedTime == null || isPolicyUpdated()) {
+                if (isPolicyUpdated()) {
                     effectivePolicy = calculateEffectivePolicy();
                     lastPolicyCalculatedTime = new Date();
+                    lastPolicyCalculatedVersion = getMaxPolicyVersion();
                 }
             }
         }
@@ -284,31 +286,33 @@ public class AxisMessage extends AxisDescription {
     }
 
     public boolean isPolicyUpdated() {
-        // AxisMessage
-        if (getPolicySubject().getLastUpdatedTime().after(
-                lastPolicyCalculatedTime)) {
-            return true;
-        }
+        return getMaxPolicyVersion() > lastPolicyCalculatedVersion;
+    }
+
+    /**
+     * Returns the maximum policy version across the description hierarchy.
+     * Uses monotonic counter instead of Date to avoid the millisecond-
+     * granularity race condition in AXIS2-5904.
+     */
+    private long getMaxPolicyVersion() {
+        long max = getPolicySubject().getVersion();
         // AxisOperation
         AxisOperation axisOperation = (AxisOperation) parent;
-        if (axisOperation != null
-                && axisOperation.getPolicySubject().getLastUpdatedTime().after(
-                lastPolicyCalculatedTime)) {
-            return true;
+        if (axisOperation != null) {
+            max = Math.max(max, axisOperation.getPolicySubject().getVersion());
         }
         // AxisService
         AxisService axisService = (axisOperation == null) ? null
                 : axisOperation.getAxisService();
-        if (axisService != null
-                && axisService.getPolicySubject().getLastUpdatedTime().after(
-                lastPolicyCalculatedTime)) {
-            return true;
+        if (axisService != null) {
+            max = Math.max(max, axisService.getPolicySubject().getVersion());
         }
         // AxisConfiguration
         AxisConfiguration axisConfiguration = (axisService == null) ? null
                 : axisService.getAxisConfiguration();
-        return axisConfiguration != null
-               && axisConfiguration.getPolicySubject().getLastUpdatedTime()
-                .after(lastPolicyCalculatedTime);
+        if (axisConfiguration != null) {
+            max = Math.max(max, 
axisConfiguration.getPolicySubject().getVersion());
+        }
+        return max;
     }
 }

Reply via email to