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

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 0224097325fc8d173982942f0dfa17c46d8cd2b5
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Wed Aug 27 14:44:47 2025 +0200

    Fix a race condition causing a random test failure.
---
 .../operation/transform/ConcatenatedTransform.java        | 15 ++++++++++-----
 .../operation/transform/EllipsoidToRadiusTransform.java   |  6 +++++-
 .../sis/referencing/operation/transform/PoleRotation.java |  1 +
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
index 968cc4e2d2..d5b1077998 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/ConcatenatedTransform.java
@@ -875,13 +875,18 @@ class ConcatenatedTransform extends AbstractMathTransform 
implements Serializabl
      * If the given transform is an instance of {@code ConcatenatedTransform}, 
sets its inverse to the given value.
      * Otherwise does nothing.
      *
-     * @param  tr       the transform on which to set the inverse.
+     * <h4>Thread safety</h4>
+     * If {@code forward} is an instance of {@link ConcatenatedTransform}, 
then it should be a newly created instance.
+     * Users should not have the possibility to interact with that transform 
before {@code forward.inverse} is set.
+     *
+     * @param  forward  the transform on which to set the inverse.
      * @param  inverse  the inverse to assign to the given transform.
      */
-    static void setInverse(final MathTransform tr, final MathTransform 
inverse) {
-        if (tr instanceof ConcatenatedTransform) {
-            assert 
OnewayLinearTransform.isNullOrDelegate(((ConcatenatedTransform) tr).inverse, 
inverse);
-            ((ConcatenatedTransform) tr).inverse = inverse;
+    static void setInverse(final MathTransform forward, final MathTransform 
inverse) {
+        if (forward instanceof ConcatenatedTransform) {
+            final var ct = (ConcatenatedTransform) forward;
+            assert OnewayLinearTransform.isNullOrDelegate(ct.inverse, inverse);
+            ct.inverse = inverse;
         }
     }
 
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToRadiusTransform.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToRadiusTransform.java
index 06e6f10552..ff7e63f12a 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToRadiusTransform.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/EllipsoidToRadiusTransform.java
@@ -204,10 +204,14 @@ public class EllipsoidToRadiusTransform extends 
AbstractMathTransform implements
      * @return the conversion from two-dimensional to three-dimensional 
spherical coordinates.
      * @throws FactoryException if an error occurred while creating a 
transform.
      */
-    public static MathTransform createGeodeticConversion(final 
MathTransformFactory factory, final Ellipsoid surface)
+    public static MathTransform createGeodeticConversion(MathTransformFactory 
factory, final Ellipsoid surface)
             throws FactoryException
     {
         if (Formulas.isEllipsoidal(surface)) try {
+            if (factory instanceof DefaultMathTransformFactory) {
+                factory = ((DefaultMathTransformFactory) 
factory).caching(false);
+                // We need non-shared instance because we will modify the 
inverse.
+            }
             final var kernel = new EllipsoidToRadiusTransform(surface);
             final MathTransform complete = 
kernel.context.completeTransform(factory, kernel);
             /*
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/PoleRotation.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/PoleRotation.java
index 50f2f7c465..8bea81c5ba 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/PoleRotation.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/PoleRotation.java
@@ -483,6 +483,7 @@ public class PoleRotation extends AbstractMathTransform2D 
implements Serializabl
                         alternative,
                         concatenate(actualParameters,  
ContextualParameters.MatrixRole.DENORMALIZATION,
                                     inverseParameters, 
ContextualParameters.MatrixRole.INVERSE_DENORMALIZATION));
+                ConcatenatedTransform.setInverse(inverse, this);
             } else {
                 inverse = simple;
             }

Reply via email to