You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2022/08/02 17:32:54 UTC

[brooklyn-server] branch master updated (58608dd79b -> d68ff02b08)

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

heneveld pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git


    from 58608dd79b Merge pull request #1348 from ahgittin/interrupt-sshj
     new 105b661ba1 catch other case where interrupt might be swallowed
     new 552b5ecc1e more checks to prevent sshj swallowing thread interruptions
     new eed49eeb70 simplify exceptions we throw for interruption
     new aa69987c77 downgrade messages to trace
     new b0282af969 even more checks for sshj task interruption
     new d68ff02b08 Merge branch 'master' of https://gitbox.apache.org/repos/asf/brooklyn-server

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../util/core/internal/ssh/sshj/SshjTool.java      | 60 +++++++++++----
 .../internal/ssh/sshj/SshjToolIntegrationTest.java | 90 +++++++++++++++-------
 .../brooklyn/util/exceptions/Exceptions.java       | 16 ++--
 3 files changed, 111 insertions(+), 55 deletions(-)


[brooklyn-server] 01/06: catch other case where interrupt might be swallowed

Posted by he...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit 105b661ba152f19f12ccafef58ea35174dd381fb
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Tue Aug 2 11:29:36 2022 +0100

    catch other case where interrupt might be swallowed
---
 .../util/core/internal/ssh/sshj/SshjTool.java      | 35 ++++++++++------
 .../internal/ssh/sshj/SshjToolIntegrationTest.java | 49 +++++++++-------------
 2 files changed, 43 insertions(+), 41 deletions(-)

diff --git a/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java b/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java
index 9c379cf6ed..ddc96ad611 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java
@@ -44,7 +44,6 @@ import org.apache.brooklyn.util.core.internal.ssh.ShellTool;
 import org.apache.brooklyn.util.core.internal.ssh.SshAbstractTool;
 import org.apache.brooklyn.util.core.internal.ssh.SshTool;
 import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.exceptions.RuntimeInterruptedException;
 import org.apache.brooklyn.util.exceptions.RuntimeTimeoutException;
 import org.apache.brooklyn.util.repeat.Repeater;
 import org.apache.brooklyn.util.stream.KnownSizeInputStream;
@@ -67,7 +66,6 @@ import java.util.concurrent.atomic.AtomicReference;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Throwables.getCausalChain;
-import static com.google.common.base.Throwables.getRootCause;
 import static com.google.common.collect.Iterables.any;
 
 /**
@@ -646,7 +644,7 @@ public class SshjTool extends SshAbstractTool implements SshTool {
                 } catch (Exception e2) {
                     LOG.debug("<< ("+toString()+") error closing connection: "+e+" / "+e2, e);
                 }
-                if (Thread.currentThread().isInterrupted()) {
+                if (checkInterrupted(e)) {
                     LOG.debug("<< {} (rethrowing, interrupted): {}", fullMessage, e.getMessage());
                     throw propagate(e, fullMessage + "; interrupted");
                 }
@@ -797,7 +795,7 @@ public class SshjTool extends SshAbstractTool implements SshTool {
         }
     }
 
-    // TODO simpler not to use predicates
+    // TODO simpler not to use predicates (this seems not to be used)
     @VisibleForTesting
     Predicate<String> causalChainHasMessageContaining(final Exception from) {
         return new Predicate<String>() {
@@ -1003,12 +1001,16 @@ public class SshjTool extends SshAbstractTool implements SshTool {
                         try {
                             shell.join(1000, TimeUnit.MILLISECONDS);
                         } catch (ConnectionException e) {
-                            LOG.debug("SshjTool exception joining shell", e);
-                            if (isNonRetryableException(e)) {
-                                throw e;
+                            if (Throwables.getRootCause(e) instanceof TimeoutException) {
+                                // normal, do nothing
+                            } else {
+                                LOG.debug("SshjTool exception joining shell", e);
+                                if (isNonRetryableException(e)) {
+                                    throw e;
+                                }
+                                // don't automatically give up here, it might be a transient network failure
+                                last = e;
                             }
-                            // don't automatically give up here, it might be a transient network failure
-                            last = e;
                         }
                         LOG.info("SshjTool looping waiting for shell; thread "+Thread.currentThread()+" interrupted? "+Thread.currentThread().isInterrupted());
                         if (endBecauseReturned) {
@@ -1061,12 +1063,21 @@ public class SshjTool extends SshAbstractTool implements SshTool {
         }
     }
 
-    protected boolean isNonRetryableException(ConnectionException e) throws ConnectionException {
-        if (Exceptions.isRootCauseIsInterruption(e)) {
-            // if we don't check for ^ wrapped in e then the interrupt is swallowed; that's how sshj works :(
+    protected boolean checkInterrupted(Throwable t) {
+        if (Thread.currentThread().isInterrupted()) return true;
+        if (t!=null && Exceptions.isRootCauseIsInterruption(t)) {
+            // sshj has an ugly habit of catching & clearing thread interrupts, and returning wrapped in ConnectionExceptions
+            // restore the interrupt if this is the case
             Thread.currentThread().interrupt();
             return true;
         }
+        return false;
+    }
+
+    protected boolean isNonRetryableException(ConnectionException e) throws ConnectionException {
+        if (checkInterrupted(e)) {
+            return true;
+        }
         // anything else assume transient network failure until something else (eg shell) times out
         return false;
     }
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjToolIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjToolIntegrationTest.java
index 22082c95eb..e5309ab3d4 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjToolIntegrationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjToolIntegrationTest.java
@@ -18,34 +18,16 @@
  */
 package org.apache.brooklyn.util.core.internal.ssh.sshj;
 
-import static org.apache.brooklyn.util.core.internal.ssh.ShellTool.PROP_ERR_STREAM;
-import static org.apache.brooklyn.util.core.internal.ssh.ShellTool.PROP_OUT_STREAM;
-import static org.apache.brooklyn.util.time.Duration.FIVE_SECONDS;
-import static org.apache.brooklyn.util.time.Duration.ONE_SECOND;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicReference;
-
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import net.schmizz.sshj.connection.channel.direct.Session;
 import org.apache.brooklyn.core.BrooklynFeatureEnablement;
 import org.apache.brooklyn.test.Asserts;
 import org.apache.brooklyn.util.core.internal.ssh.ShellTool;
 import org.apache.brooklyn.util.core.internal.ssh.SshException;
 import org.apache.brooklyn.util.core.internal.ssh.SshTool;
 import org.apache.brooklyn.util.core.internal.ssh.SshToolAbstractIntegrationTest;
-import org.apache.brooklyn.util.core.task.ssh.SshPutTaskFactory;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.exceptions.RuntimeTimeoutException;
 import org.apache.brooklyn.util.os.Os;
@@ -55,11 +37,21 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.testng.annotations.Test;
 
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
 
-import net.schmizz.sshj.connection.channel.direct.Session;
+import static org.apache.brooklyn.util.core.internal.ssh.ShellTool.PROP_ERR_STREAM;
+import static org.apache.brooklyn.util.core.internal.ssh.ShellTool.PROP_OUT_STREAM;
+import static org.apache.brooklyn.util.time.Duration.ONE_SECOND;
+import static org.testng.Assert.*;
 
 /**
  * Test the operation of the {@link SshjTool} utility class.
@@ -345,7 +337,7 @@ public class SshjToolIntegrationTest extends SshToolAbstractIntegrationTest {
         return outstr;
     }
 
-    @Test(groups = {"Integration"})
+    @Test(groups = {"Integration"}, invocationCount = 10)
     public void testSshIsInterrupted() {
         log.info("STARTING");
         final SshTool localTool = new SshjTool(ImmutableMap.of(
@@ -375,14 +367,13 @@ public class SshjToolIntegrationTest extends SshToolAbstractIntegrationTest {
             });
             log.info("STARTING");
             t.start();
-            Time.sleep(FIVE_SECONDS);
+            if (Math.random()>0.1) Time.sleep(Duration.millis(3*Math.random()*Math.random()));  // sleep for a small amount of time, up to three seconds, but usually much less, and 10% of time not at all
             log.info("INTERRUPTING");
             t.interrupt();
             Time.sleep(ONE_SECOND);
             Arrays.asList(t.getStackTrace()).forEach(traceElement -> System.out.println(traceElement));
             log.info("JOINING");
             Stopwatch s = Stopwatch.createStarted();
-            t.join();
             if (Duration.of(s.elapsed()).isLongerThan(ONE_SECOND)) {
                 Asserts.fail("Join should have been immediate as other thread was interrupted, but instead took "+Duration.of(s.elapsed()));
             }


[brooklyn-server] 05/06: even more checks for sshj task interruption

Posted by he...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit b0282af9699d732b2eae28a29c06d2b488f7efe2
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Tue Aug 2 16:51:08 2022 +0100

    even more checks for sshj task interruption
---
 .../util/core/internal/ssh/sshj/SshjTool.java      | 10 +++++
 .../internal/ssh/sshj/SshjToolIntegrationTest.java | 45 +++++++++++++++++++++-
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java b/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java
index 06a9579df8..98d73bedac 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java
@@ -38,11 +38,13 @@ import net.schmizz.sshj.transport.TransportException;
 import net.schmizz.sshj.xfer.FileSystemFile;
 import net.schmizz.sshj.xfer.InMemorySourceFile;
 import net.schmizz.sshj.xfer.LocalDestFile;
+import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.core.BrooklynFeatureEnablement;
 import org.apache.brooklyn.util.core.internal.ssh.BackoffLimitedRetryHandler;
 import org.apache.brooklyn.util.core.internal.ssh.ShellTool;
 import org.apache.brooklyn.util.core.internal.ssh.SshAbstractTool;
 import org.apache.brooklyn.util.core.internal.ssh.SshTool;
+import org.apache.brooklyn.util.core.task.Tasks;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.exceptions.RuntimeTimeoutException;
 import org.apache.brooklyn.util.repeat.Repeater;
@@ -1069,6 +1071,8 @@ public class SshjTool extends SshAbstractTool implements SshTool {
     }
 
     protected boolean checkInterrupted(Throwable t) {
+        // see https://github.com/hierynomus/sshj/issues/800 -- we are trying to improve SSHJ so that the thread should keep its interrupted state
+
         if (Thread.currentThread().isInterrupted()) return true;
         if (t!=null && Exceptions.isRootCauseIsInterruption(t)) {
             // sshj has an ugly habit of catching & clearing thread interrupts, and returning wrapped in ConnectionExceptions
@@ -1076,6 +1080,12 @@ public class SshjTool extends SshAbstractTool implements SshTool {
             Thread.currentThread().interrupt();
             return true;
         }
+        Task<?> task = Tasks.current();
+        if (task!=null && task.isCancelled()) {
+            //  interrupt flag and exception might not tell the whole story; if we have a context task let's use it also
+            Thread.currentThread().interrupt();
+            return true;
+        }
         return false;
     }
 
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjToolIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjToolIntegrationTest.java
index e5309ab3d4..2ffeb1ddc7 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjToolIntegrationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjToolIntegrationTest.java
@@ -21,7 +21,14 @@ package org.apache.brooklyn.util.core.internal.ssh.sshj;
 import com.google.common.base.Stopwatch;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import net.schmizz.concurrent.ExceptionChainer;
+import net.schmizz.sshj.common.SSHException;
+import net.schmizz.sshj.common.StreamCopier;
+import net.schmizz.sshj.connection.ConnectionException;
 import net.schmizz.sshj.connection.channel.direct.Session;
+import net.schmizz.sshj.sftp.SFTPException;
+import net.schmizz.sshj.transport.TransportException;
+import net.schmizz.sshj.userauth.UserAuthException;
 import org.apache.brooklyn.core.BrooklynFeatureEnablement;
 import org.apache.brooklyn.test.Asserts;
 import org.apache.brooklyn.util.core.internal.ssh.ShellTool;
@@ -39,6 +46,8 @@ import org.testng.annotations.Test;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
 import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -337,7 +346,41 @@ public class SshjToolIntegrationTest extends SshToolAbstractIntegrationTest {
         return outstr;
     }
 
-    @Test(groups = {"Integration"}, invocationCount = 10)
+    // useful if we want to understand why SSHJ is swallowing the exceptions;
+    // shouldn't be needed once we have a solution to https://github.com/hierynomus/sshj/issues/800
+//    static void hackChainerLogging() {
+//        Arrays.asList(SSHException.class, ConnectionException.class, TransportException.class, SFTPException.class, UserAuthException.class
+//                // , StreamCopier.class   // not a public field
+//        ).forEach(clazz -> {
+//            try {
+//                Field f = clazz.getField("chainer");
+//                f.setAccessible(true);
+//
+//                Field modifiersField = Field.class.getDeclaredField("modifiers");
+//                modifiersField.setAccessible(true);
+//                modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);
+//
+//                ExceptionChainer oldValue = (ExceptionChainer) f.get(null);
+//                f.set(null, new ExceptionChainer() {
+//                    @Override
+//                    public Throwable chain(Throwable t) {
+//                        if (Exceptions.isRootCauseIsInterruption(t)) {
+//                            log.warn("Caught interruption (thread interrupted? "+Thread.currentThread().isInterrupted()+")", t);
+//                            log.warn("... caught at", new Throwable("source of catching, in " + clazz));
+//                        }
+//                        return oldValue.chain(t);
+//                    }
+//                });
+//            } catch (Exception e) {
+//                throw Exceptions.propagate(e);
+//            }
+//        });
+//    }
+//    static {
+//        hackChainerLogging();
+//    }
+
+    @Test(groups = {"Integration"})
     public void testSshIsInterrupted() {
         log.info("STARTING");
         final SshTool localTool = new SshjTool(ImmutableMap.of(


[brooklyn-server] 03/06: simplify exceptions we throw for interruption

Posted by he...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit eed49eeb702b5a7d5d7ab9ad85e1727e2701037f
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Tue Aug 2 13:27:43 2022 +0100

    simplify exceptions we throw for interruption
---
 .../src/main/java/org/apache/brooklyn/util/exceptions/Exceptions.java    | 1 +
 1 file changed, 1 insertion(+)

diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/exceptions/Exceptions.java b/utils/common/src/main/java/org/apache/brooklyn/util/exceptions/Exceptions.java
index 7b7590dc5c..f4a7affb1d 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/exceptions/Exceptions.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/exceptions/Exceptions.java
@@ -184,6 +184,7 @@ public class Exceptions {
         if (throwable!=null && (throwable instanceof InterruptedException || throwable instanceof RuntimeInterruptedException || Exceptions.isRootCauseIsInterruption(throwable))) {
             // previously only interrupted if we caught RuntimeInterrupted; but best seems to be to always set the interrupted bit
             Thread.currentThread().interrupt();
+            if (throwable instanceof RuntimeException) throw (RuntimeException) throwable;
             throw new RuntimeInterruptedException(throwable);
         }
     }


[brooklyn-server] 04/06: downgrade messages to trace

Posted by he...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit aa69987c77d978fdd7c2f232b885d4e1527964cd
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Tue Aug 2 13:55:59 2022 +0100

    downgrade messages to trace
---
 .../org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java    | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java b/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java
index f953286ea5..06a9579df8 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java
@@ -991,10 +991,10 @@ public class SshjTool extends SshAbstractTool implements SshTool {
                 closeWhispering(output, this);
 
                 boolean timedOut = false;
+                Exception last = null;
                 try {
                     long timeoutMillis = Math.min(timeout.toMilliseconds(), Integer.MAX_VALUE);
                     long timeoutEnd = System.currentTimeMillis() + timeoutMillis;
-                    Exception last = null;
                     do {
                         if (!shell.isOpen() && ((SessionChannel)session).getExitStatus()!=null)
                             // shell closed, and exit status returned
@@ -1015,8 +1015,8 @@ public class SshjTool extends SshAbstractTool implements SshTool {
                                 // don't automatically give up here, it might be a transient network failure
                                 last = e;
                             }
+                            LOG.trace("SshjTool threw exception joining shell (timeouts are normal)", e);
                         }
-                        LOG.info("SshjTool looping waiting for shell; thread "+Thread.currentThread()+" interrupted? "+Thread.currentThread().isInterrupted());
                         if (endBecauseReturned) {
                             // shell is still open, ie some process is running
                             // but we have a result code, so main shell is finished
@@ -1036,6 +1036,7 @@ public class SshjTool extends SshAbstractTool implements SshTool {
                     }
                     return ((SessionChannel)session).getExitStatus();
                 } finally {
+                    LOG.trace("SshjTool shell join completed", last);
                     // wait for all stdout/stderr to have been re-directed
                     closeWhispering(shell, this);
                     shell = null;


[brooklyn-server] 02/06: more checks to prevent sshj swallowing thread interruptions

Posted by he...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit 552b5ecc1e22dc57c2a2c7439e8d414a400afa7a
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Tue Aug 2 13:25:06 2022 +0100

    more checks to prevent sshj swallowing thread interruptions
---
 .../brooklyn/util/core/internal/ssh/sshj/SshjTool.java    | 10 +++++++---
 .../org/apache/brooklyn/util/exceptions/Exceptions.java   | 15 +++++----------
 2 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java b/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java
index ddc96ad611..f953286ea5 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/internal/ssh/sshj/SshjTool.java
@@ -899,9 +899,10 @@ public class SshjTool extends SshAbstractTool implements SshTool {
                         long joinTimeout = 10*1000;
                         if (outgobbler != null) outgobbler.join(joinTimeout);
                         if (errgobbler != null) errgobbler.join(joinTimeout);
-                    } catch (InterruptedException e) {
-                        LOG.warn("Interrupted gobbling streams from ssh: "+command, e);
-                        Thread.currentThread().interrupt();
+                    } catch (Exception e) {
+                        if (checkInterrupted(e)) {
+                            LOG.warn("Interrupted gobbling streams from ssh: " + command, e);
+                        }
                     }
                 }
 
@@ -975,6 +976,9 @@ public class SshjTool extends SshAbstractTool implements SshTool {
                         output.write(toUTF8ByteArray(cmd+"\n"));
                         output.flush();
                     } catch (ConnectionException e) {
+                        if (checkInterrupted(e)) {
+                            throw e;
+                        }
                         if (!shell.isOpen()) {
                             // shell is closed; presumably the user command did `exit`
                             if (LOG.isDebugEnabled()) LOG.debug("Shell closed to {} when executing {}", SshjTool.this.toString(), commands);
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/exceptions/Exceptions.java b/utils/common/src/main/java/org/apache/brooklyn/util/exceptions/Exceptions.java
index 29a9300b63..7b7590dc5c 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/exceptions/Exceptions.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/exceptions/Exceptions.java
@@ -120,12 +120,8 @@ public class Exceptions {
      * <li> wraps as PropagatedRuntimeException for easier filtering
      */
     public static RuntimeException propagate(Throwable throwable) {
-        if (throwable instanceof InterruptedException || throwable instanceof RuntimeInterruptedException || Exceptions.isRootCauseIsInterruption(throwable)) {
-            // previously only interrupted if we caught RuntimeInterrupted; but best seems to be to always set the interrupted bit
-            Thread.currentThread().interrupt();
-            throw new RuntimeInterruptedException(throwable);
-        }
-        Throwables.propagateIfPossible(checkNotNull(throwable));
+        propagateIfInterrupt(throwable);
+        Throwables.throwIfUnchecked(throwable);
         throw new PropagatedRuntimeException(throwable);
     }
 
@@ -185,11 +181,10 @@ public class Exceptions {
      * or {@link RuntimeInterruptedException}.
      */
     public static void propagateIfInterrupt(Throwable throwable) {
-        if (throwable instanceof InterruptedException) {
-            throw new RuntimeInterruptedException(throwable);
-        } else if (throwable instanceof RuntimeInterruptedException) {
+        if (throwable!=null && (throwable instanceof InterruptedException || throwable instanceof RuntimeInterruptedException || Exceptions.isRootCauseIsInterruption(throwable))) {
+            // previously only interrupted if we caught RuntimeInterrupted; but best seems to be to always set the interrupted bit
             Thread.currentThread().interrupt();
-            throw (RuntimeInterruptedException) throwable;
+            throw new RuntimeInterruptedException(throwable);
         }
     }
 


[brooklyn-server] 06/06: Merge branch 'master' of https://gitbox.apache.org/repos/asf/brooklyn-server

Posted by he...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit d68ff02b080054691c37db3be63cb82de2bb0387
Merge: b0282af969 58608dd79b
Author: Alex Heneveld <al...@cloudsoft.io>
AuthorDate: Tue Aug 2 18:32:42 2022 +0100

    Merge branch 'master' of https://gitbox.apache.org/repos/asf/brooklyn-server