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

cstamas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git


The following commit(s) were added to refs/heads/master by this push:
     new 7395cd45 [MRESOLVER-220] Refuse proactively unsupported operation 
(#301)
7395cd45 is described below

commit 7395cd4584005e37fe7fe67b8cf3949c0c21aad1
Author: Tamas Cservenak <[email protected]>
AuthorDate: Tue Jun 20 14:51:45 2023 +0200

    [MRESOLVER-220] Refuse proactively unsupported operation (#301)
    
    Instead to silently "send result" (that is false/code expect true=success) 
to caller, as this makes totally strange outcome: "failed to lock within 30sec" 
but caller did not wait anything. Moreover, the bug where upgrade is attempted 
slips in unnoticed.
    
    In short: it was totally wrong that lock implementation immediately returns 
"false", hiding the fact that user attempted non supported operation.
    
    ---
    
    https://issues.apache.org/jira/browse/MRESOLVER-220
---
 .../NamedLockFactoryAdapterTestSupport.java        |  4 +--
 .../NamedLockFactoryAdapterTestSupport.java        |  3 +-
 .../hazelcast/NamedLockFactoryTestSupport.java     |  7 ++++-
 .../named/support/AdaptedSemaphoreNamedLock.java   |  2 +-
 .../aether/named/support/FileLockNamedLock.java    |  2 +-
 .../support/LockUpgradeNotSupportedException.java  | 36 ++++++++++++++++++++++
 .../named/support/ReadWriteLockNamedLock.java      |  2 +-
 .../org/eclipse/aether/named/support/Retry.java    | 22 +++++++++++++
 .../aether/named/NamedLockFactoryTestSupport.java  |  7 ++++-
 9 files changed, 77 insertions(+), 8 deletions(-)

diff --git 
a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/synccontext/NamedLockFactoryAdapterTestSupport.java
 
b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/synccontext/NamedLockFactoryAdapterTestSupport.java
index b647c07a..43f0eab4 100644
--- 
a/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/synccontext/NamedLockFactoryAdapterTestSupport.java
+++ 
b/maven-resolver-impl/src/test/java/org/eclipse/aether/internal/impl/synccontext/NamedLockFactoryAdapterTestSupport.java
@@ -31,6 +31,7 @@ import org.eclipse.aether.SyncContext;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.eclipse.aether.internal.impl.synccontext.named.*;
 import org.eclipse.aether.named.NamedLockFactory;
+import org.eclipse.aether.named.support.LockUpgradeNotSupportedException;
 import org.eclipse.aether.repository.LocalRepository;
 import org.eclipse.aether.spi.synccontext.SyncContextFactory;
 import org.junit.AfterClass;
@@ -266,8 +267,7 @@ public abstract class NamedLockFactoryAdapterTestSupport {
                         chained.run();
                     }
                     loser.await();
-                } catch (IllegalStateException e) {
-                    e.printStackTrace(); // for ref purposes
+                } catch (IllegalStateException | 
LockUpgradeNotSupportedException e) {
                     loser.countDown();
                     winner.await();
                 }
diff --git 
a/maven-resolver-named-locks-hazelcast/src/test/java/org/eclipse/aether/named/hazelcast/NamedLockFactoryAdapterTestSupport.java
 
b/maven-resolver-named-locks-hazelcast/src/test/java/org/eclipse/aether/named/hazelcast/NamedLockFactoryAdapterTestSupport.java
index f7e031b0..b5a57ca9 100644
--- 
a/maven-resolver-named-locks-hazelcast/src/test/java/org/eclipse/aether/named/hazelcast/NamedLockFactoryAdapterTestSupport.java
+++ 
b/maven-resolver-named-locks-hazelcast/src/test/java/org/eclipse/aether/named/hazelcast/NamedLockFactoryAdapterTestSupport.java
@@ -33,6 +33,7 @@ import 
org.eclipse.aether.internal.impl.synccontext.named.DiscriminatingNameMapp
 import org.eclipse.aether.internal.impl.synccontext.named.GAVNameMapper;
 import 
org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapter;
 import org.eclipse.aether.named.NamedLockFactory;
+import org.eclipse.aether.named.support.LockUpgradeNotSupportedException;
 import org.eclipse.aether.repository.LocalRepository;
 import org.eclipse.aether.spi.synccontext.SyncContextFactory;
 import org.junit.AfterClass;
@@ -230,7 +231,7 @@ public abstract class NamedLockFactoryAdapterTestSupport {
                         chained.run();
                     }
                     loser.await();
-                } catch (IllegalStateException e) {
+                } catch (IllegalStateException | 
LockUpgradeNotSupportedException e) {
                     loser.countDown();
                     winner.await();
                 }
diff --git 
a/maven-resolver-named-locks-hazelcast/src/test/java/org/eclipse/aether/named/hazelcast/NamedLockFactoryTestSupport.java
 
b/maven-resolver-named-locks-hazelcast/src/test/java/org/eclipse/aether/named/hazelcast/NamedLockFactoryTestSupport.java
index ad11bddc..bc1c779a 100644
--- 
a/maven-resolver-named-locks-hazelcast/src/test/java/org/eclipse/aether/named/hazelcast/NamedLockFactoryTestSupport.java
+++ 
b/maven-resolver-named-locks-hazelcast/src/test/java/org/eclipse/aether/named/hazelcast/NamedLockFactoryTestSupport.java
@@ -23,6 +23,7 @@ import java.util.concurrent.TimeUnit;
 
 import org.eclipse.aether.named.NamedLock;
 import org.eclipse.aether.named.NamedLockFactory;
+import org.eclipse.aether.named.support.LockUpgradeNotSupportedException;
 import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.Rule;
@@ -114,7 +115,11 @@ public abstract class NamedLockFactoryTestSupport {
         final String name = testName.getMethodName();
         try (NamedLock one = namedLockFactory.getLock(name)) {
             assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true));
-            assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), 
is(false));
+            try {
+                one.lockExclusively(1L, TimeUnit.MILLISECONDS);
+            } catch (LockUpgradeNotSupportedException e) {
+                // good
+            }
             one.unlock();
         }
     }
diff --git 
a/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/AdaptedSemaphoreNamedLock.java
 
b/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/AdaptedSemaphoreNamedLock.java
index f3be9665..4b282de1 100644
--- 
a/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/AdaptedSemaphoreNamedLock.java
+++ 
b/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/AdaptedSemaphoreNamedLock.java
@@ -87,7 +87,7 @@ public class AdaptedSemaphoreNamedLock extends 
NamedLockSupport {
                 perms.push(NONE);
                 return true;
             } else {
-                return false; // Lock upgrade not supported
+                throw new LockUpgradeNotSupportedException(this); // Lock 
upgrade not supported
             }
         }
         if (semaphore.tryAcquire(EXCLUSIVE, time, unit)) {
diff --git 
a/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/FileLockNamedLock.java
 
b/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/FileLockNamedLock.java
index e69dba93..c70418fb 100644
--- 
a/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/FileLockNamedLock.java
+++ 
b/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/FileLockNamedLock.java
@@ -137,7 +137,7 @@ public final class FileLockNamedLock extends 
NamedLockSupport {
                         // if we own shared, that's attempted upgrade
                         boolean weOwnShared = steps.contains(Boolean.TRUE);
                         if (weOwnShared) {
-                            return false; // Lock upgrade not supported
+                            throw new LockUpgradeNotSupportedException(this); 
// Lock upgrade not supported
                         } else {
                             // someone else owns shared, let's wait
                             return null;
diff --git 
a/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/LockUpgradeNotSupportedException.java
 
b/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/LockUpgradeNotSupportedException.java
new file mode 100644
index 00000000..7cd7b137
--- /dev/null
+++ 
b/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/LockUpgradeNotSupportedException.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.eclipse.aether.named.support;
+
+/**
+ * Exception thrown when lock upgrade attempted that we do not support. This 
exception when used within {@link Retry}
+ * helper should never be reattempted, hence is marked with {@link 
Retry.DoNotRetry} marker.
+ *
+ * @since 1.9.13
+ */
+public final class LockUpgradeNotSupportedException extends RuntimeException 
implements Retry.DoNotRetry {
+    /**
+     * Constructor for case, when current thread attempts lock upgrade on 
given lock instance.
+     */
+    public LockUpgradeNotSupportedException(NamedLockSupport namedLock) {
+        super("Thread " + Thread.currentThread().getName()
+                + " already holds shared lock for '" + namedLock.name()
+                + "', but asks for exclusive lock; lock upgrade not 
supported");
+    }
+}
diff --git 
a/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/ReadWriteLockNamedLock.java
 
b/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/ReadWriteLockNamedLock.java
index df49e958..cb81818d 100644
--- 
a/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/ReadWriteLockNamedLock.java
+++ 
b/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/ReadWriteLockNamedLock.java
@@ -67,7 +67,7 @@ public class ReadWriteLockNamedLock extends NamedLockSupport {
         Deque<Step> steps = threadSteps.get();
         if (!steps.isEmpty()) { // we already own shared or exclusive lock
             if (!steps.contains(Step.EXCLUSIVE)) {
-                return false; // Lock upgrade not supported
+                throw new LockUpgradeNotSupportedException(this); // Lock 
upgrade not supported
             }
         }
         if (readWriteLock.writeLock().tryLock(time, unit)) {
diff --git 
a/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/Retry.java
 
b/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/Retry.java
index 7cc6a9c4..0dad803c 100644
--- 
a/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/Retry.java
+++ 
b/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/support/Retry.java
@@ -37,6 +37,14 @@ import org.slf4j.LoggerFactory;
 public final class Retry {
     private static final Logger LOGGER = LoggerFactory.getLogger(Retry.class);
 
+    /**
+     * Marker interface to apply onto exceptions to make them "never retried" 
when thrown. This shortcuts checks with
+     * predicate, if used.
+     *
+     * @since 1.9.13
+     */
+    public interface DoNotRetry {}
+
     private Retry() {
         // no instances
     }
@@ -71,6 +79,13 @@ public final class Retry {
                 throw e;
             } catch (Exception e) {
                 LOGGER.trace("Retry attempt {}: operation failure", attempt, 
e);
+                if (e instanceof DoNotRetry) {
+                    if (e instanceof RuntimeException) {
+                        throw (RuntimeException) e;
+                    } else {
+                        throw new IllegalStateException(e);
+                    }
+                }
                 if (retryPredicate != null && !retryPredicate.test(e)) {
                     throw new IllegalStateException(e);
                 }
@@ -111,6 +126,13 @@ public final class Retry {
                 throw e;
             } catch (Exception e) {
                 LOGGER.trace("Retry attempt {}: operation failure", attempt, 
e);
+                if (e instanceof DoNotRetry) {
+                    if (e instanceof RuntimeException) {
+                        throw (RuntimeException) e;
+                    } else {
+                        throw new IllegalStateException(e);
+                    }
+                }
                 if (retryPredicate != null && !retryPredicate.test(e)) {
                     throw new IllegalStateException(e);
                 }
diff --git 
a/maven-resolver-named-locks/src/test/java/org/eclipse/aether/named/NamedLockFactoryTestSupport.java
 
b/maven-resolver-named-locks/src/test/java/org/eclipse/aether/named/NamedLockFactoryTestSupport.java
index 72e07e4e..9904a1e9 100644
--- 
a/maven-resolver-named-locks/src/test/java/org/eclipse/aether/named/NamedLockFactoryTestSupport.java
+++ 
b/maven-resolver-named-locks/src/test/java/org/eclipse/aether/named/NamedLockFactoryTestSupport.java
@@ -21,6 +21,7 @@ package org.eclipse.aether.named;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+import org.eclipse.aether.named.support.LockUpgradeNotSupportedException;
 import org.junit.Assert;
 import org.junit.Rule;
 import org.junit.Test;
@@ -132,7 +133,11 @@ public abstract class NamedLockFactoryTestSupport {
         final String name = lockName();
         try (NamedLock one = namedLockFactory.getLock(name)) {
             assertThat(one.lockShared(1L, TimeUnit.MILLISECONDS), is(true));
-            assertThat(one.lockExclusively(1L, TimeUnit.MILLISECONDS), 
is(false));
+            try {
+                one.lockExclusively(1L, TimeUnit.MILLISECONDS);
+            } catch (LockUpgradeNotSupportedException e) {
+                // good
+            }
             one.unlock();
         }
     }

Reply via email to