From e40ab10549c125fe7957dc9ce35c9590f0089117 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Thu, 17 Nov 2022 22:37:10 +0100 Subject: [PATCH 1/5] some debugging stuff, revert me later please. --- lib/jul | 2 +- .../bco/dal/control/action/ActionImpl.java | 15 +++++++++++--- .../layer/unit/AbstractUnitController.java | 20 ++++++++++++++++--- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/lib/jul b/lib/jul index 6a7a1908ed..d1dd2405e9 160000 --- a/lib/jul +++ b/lib/jul @@ -1 +1 @@ -Subproject commit 6a7a1908eda054ac3b8e9cde166be814e439753c +Subproject commit d1dd2405e995667dee725cc0807f9760d511c416 diff --git a/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java b/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java index 2c09fd0170..a20acbe163 100644 --- a/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java +++ b/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java @@ -300,7 +300,9 @@ public Future execute() { } // apply new state + LOGGER.error("[" +myId+"]"+" performOperationService: "+ actionTask.hashCode()); unit.performOperationService(serviceState, serviceDescription.getServiceType()).get(EXECUTION_FAILURE_TIMEOUT, TimeUnit.MILLISECONDS); + LOGGER.error("[" +myId+"]"+" performOperationService end: "+ actionTask.hashCode()); updateActionStateIfNotCanceled(State.EXECUTING); @@ -719,7 +721,10 @@ private void cancelActionTask() { // cancel if exist if (actionTask != null) { + LOGGER.warn("[" +myId+"]"+" cancel["+actionTask.isDone()+"] and interrupt "+ actionTask.hashCode()); actionTask.cancel(true); + } else { + LOGGER.warn("[" +myId+"]"+" no interruption performed"); } try { @@ -733,7 +738,7 @@ private void cancelActionTask() { // check if finished after force if (!isActionTaskFinished()) { - LOGGER.error("Can not finalize " + this + " it seems the execution has stuck."); + LOGGER.error("[" +myId+"]"+" Can not cancel " + this + " it seems the execution has stuck."); StackTracePrinter.printAllStackTraces(null, ActionImpl.class, LOGGER, LogLevel.WARN); StackTracePrinter.detectDeadLocksAndPrintStackTraces(LOGGER); } @@ -760,10 +765,14 @@ private void updateActionStateWhileHoldingWriteLock(final ActionState.State stat } } + private String myId = ""; + private void updateActionState(final ActionState.State state) throws InterruptedException { actionDescriptionBuilderLock.lockWriteInterruptibly(); try { + myId = getActionDescription().getActionId() + " - " + MultiLanguageTextProcessor.getBestMatch(getActionDescription().getDescription(), "?"); + // duplicated state confirmation should be ok to simplify the code, but than skip the update. if (getActionState() == state) { return; @@ -808,10 +817,10 @@ private void updateActionState(final ActionState.State state) throws Interrupted } // print update in debug mode - if (JPService.debugMode()) { +// if (JPService.debugMode()) { LOGGER.info("State[" + state.name() + "] " + this); //StackTracePrinter.printStackTrace(LOGGER, LogLevel.INFO); - } +// } // perform the update actionDescriptionBuilder.getActionStateBuilder().setValue(state); diff --git a/module/dal/control/src/main/java/org/openbase/bco/dal/control/layer/unit/AbstractUnitController.java b/module/dal/control/src/main/java/org/openbase/bco/dal/control/layer/unit/AbstractUnitController.java index 7ecf047ea1..703a7bc53a 100644 --- a/module/dal/control/src/main/java/org/openbase/bco/dal/control/layer/unit/AbstractUnitController.java +++ b/module/dal/control/src/main/java/org/openbase/bco/dal/control/layer/unit/AbstractUnitController.java @@ -1369,10 +1369,22 @@ public void shutdown() { @Override public void applyDataUpdate(Message newState, final ServiceType serviceType) throws CouldNotPerformException { try { - if (!builderSetup.tryLockWrite(5, TimeUnit.SECONDS, this)) { - throw new InvalidStateException("Unit seems to be stuck!"); + logger.error("wait for lock..."); +// if (!builderSetup.tryLockWrite(5, TimeUnit.SECONDS, this)) { +// throw new InvalidStateException("Unit seems to be stuck!"); +// } + + while (!builderSetup.tryLockWrite(100, TimeUnit.MILLISECONDS, this)) { + + if(Thread.currentThread().isInterrupted()) { + throw new InterruptedException(); + } + + logger.warn("stucked"); } + + // builder write unlock block try { try (ClosableDataBuilder dataBuilder = getDataBuilderInterruptible(this)) { @@ -1431,9 +1443,11 @@ public void applyDataUpdate(Message newState, final ServiceType serviceType) thr builderSetup.unlockWrite(NotificationStrategy.AFTER_LAST_RELEASE); } } catch (InterruptedException ex) { + logger.error("recover interruption"); Thread.currentThread().interrupt(); throw new CouldNotPerformException("Update was interrupted!",ex); - } catch (Exception ex) { + } catch (Throwable ex) { + logger.error("Failed"); throw new CouldNotPerformException("Could not apply Service[" + serviceType.name() + "] Update[" + newState + "] for " + this + "!", ex); } } From 97d7cf6469f186656c5e1bf95f906dcf9108a846 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Tue, 22 Nov 2022 20:08:16 +0100 Subject: [PATCH 2/5] fix interruption not perfomed bug by avoiding dublicated task cancelling. --- .../bco/dal/control/action/ActionImpl.java | 17 ++++++++--------- .../org/openbase/bco/dal/lib/action/Action.java | 13 +++++++++++++ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java b/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java index a20acbe163..a4b9b8d697 100644 --- a/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java +++ b/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java @@ -267,7 +267,7 @@ public Future execute() { boolean retry = false; // loop as long as task is not canceled. - while (!(Thread.currentThread().isInterrupted() || actionTask == null || actionTask.isCancelled() || getActionState() == State.CANCELING)) { + while (!(Thread.currentThread().isInterrupted() || actionTask == null || actionTask.isCancelled() || isTerminating())) { try { // wait in case of a retry if(retry) { @@ -400,7 +400,9 @@ private void waitForActionTaskFinalization(final long timeout, final TimeUnit ti final TimeoutSplitter timeoutSplitter = new TimeoutSplitter(timeout, timeUnit); synchronized (actionTaskLock) { while (!isActionTaskFinished()) { + LOGGER.warn("wait for lock"); actionTaskLock.wait(timeoutSplitter.getTime()); + LOGGER.warn("continue"); } } } @@ -723,6 +725,7 @@ private void cancelActionTask() { if (actionTask != null) { LOGGER.warn("[" +myId+"]"+" cancel["+actionTask.isDone()+"] and interrupt "+ actionTask.hashCode()); actionTask.cancel(true); + LOGGER.warn("interrupted hopefully"); } else { LOGGER.warn("[" +myId+"]"+" no interruption performed"); } @@ -746,13 +749,15 @@ private void cancelActionTask() { private void updateActionStateIfNotCanceled(final ActionState.State state) throws InterruptedException { synchronized (actionTaskLock) { - if (actionTask.isCancelled() || getActionState() == State.CANCELING) { + if (isTerminating()) { throw new InterruptedException(); } } updateActionState(state); } + + private void updateActionStateWhileHoldingWriteLock(final ActionState.State state) { if (!actionDescriptionBuilderLock.isAnyWriteLockHeldByCurrentThread()) { new FatalImplementationErrorException("Update Action description while not holding the action description write lock!", this); @@ -806,13 +811,6 @@ private void updateActionState(final ActionState.State state) throws Interrupted case ABORTING: case CANCELING: - // mark action task already as canceled, to make sure the task is not - // updating any further action states which would otherwise introduce invalid state transitions. - synchronized (actionTaskLock) { - if (!isActionTaskFinished()) { - actionTask.cancel(false); - } - } break; } @@ -849,6 +847,7 @@ private void updateActionState(final ActionState.State state) throws Interrupted } } + private void validateStateTransition(final ActionState.State state) throws InvalidStateException { // validate state transition switch (getActionState()) { diff --git a/module/dal/lib/src/main/java/org/openbase/bco/dal/lib/action/Action.java b/module/dal/lib/src/main/java/org/openbase/bco/dal/lib/action/Action.java index 949feb006e..8c3005def5 100644 --- a/module/dal/lib/src/main/java/org/openbase/bco/dal/lib/action/Action.java +++ b/module/dal/lib/src/main/java/org/openbase/bco/dal/lib/action/Action.java @@ -350,6 +350,19 @@ default boolean isDone() { }; } + /** + * Check if this action is terminating, which means it was canceled + * or aborted but has not reached a terminating state yet. + * + * @return true if canceling or aborting. + */ + default boolean isTerminating() { + return switch (getActionState()) { + case CANCELING, ABORTING -> true; + default -> false; + }; + } + /** * Return the current state of this action. * From cd7b35f0b52b277b72e04ec91699ad3633cd5247 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Tue, 22 Nov 2022 20:56:45 +0100 Subject: [PATCH 3/5] cleanup debug logging. Make user filter case insensitive. Implement further user filter test. --- .../bco/dal/control/action/ActionImpl.java | 41 ++++------- .../layer/unit/AbstractUnitController.java | 20 +----- .../unit/lib/filter/UnitConfigFilterImpl.java | 2 +- .../unit/test/UnitConfigFilterTest.kt | 70 ++++++++++++++++--- 4 files changed, 77 insertions(+), 56 deletions(-) diff --git a/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java b/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java index a4b9b8d697..8436603a67 100644 --- a/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java +++ b/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java @@ -282,12 +282,12 @@ public Future execute() { if (!isValid()) { LOGGER.debug(ActionImpl.this + " no longer valid and will be rejected!"); - updateActionStateIfNotCanceled(State.REJECTED); + updateActionStateIfNotTerminating(State.REJECTED); break; } // Submission - updateActionStateIfNotCanceled(State.SUBMISSION); + updateActionStateIfNotTerminating(State.SUBMISSION); // only update requested state if it is an operation state, else throw an exception if not in provider control mode if (hasOperationService) { @@ -300,15 +300,13 @@ public Future execute() { } // apply new state - LOGGER.error("[" +myId+"]"+" performOperationService: "+ actionTask.hashCode()); unit.performOperationService(serviceState, serviceDescription.getServiceType()).get(EXECUTION_FAILURE_TIMEOUT, TimeUnit.MILLISECONDS); - LOGGER.error("[" +myId+"]"+" performOperationService end: "+ actionTask.hashCode()); - updateActionStateIfNotCanceled(State.EXECUTING); + updateActionStateIfNotTerminating(State.EXECUTING); // action can be finished if not done yet and time has expired or execution time was never required. if (!isDone() && (isExpired() || getExecutionTimePeriod(TimeUnit.MICROSECONDS) == 0)) { - updateActionStateIfNotCanceled(State.FINISHED); + updateActionStateIfNotTerminating(State.FINISHED); } break; @@ -321,18 +319,18 @@ public Future execute() { } if (!isDone()) { - updateActionStateIfNotCanceled(State.SUBMISSION_FAILED); + updateActionStateIfNotTerminating(State.SUBMISSION_FAILED); } // handle if action was rejected by the unit itself if (ex.getCause() instanceof RejectedException) { - updateActionStateIfNotCanceled(State.REJECTED); + updateActionStateIfNotTerminating(State.REJECTED); break; } // avoid execution in case unit is shutting down if (unit.isShutdownInProgress() || ExceptionProcessor.isCausedBySystemShutdown(ex)) { - updateActionStateIfNotCanceled(State.REJECTED); + updateActionStateIfNotTerminating(State.REJECTED); break; } @@ -400,9 +398,7 @@ private void waitForActionTaskFinalization(final long timeout, final TimeUnit ti final TimeoutSplitter timeoutSplitter = new TimeoutSplitter(timeout, timeUnit); synchronized (actionTaskLock) { while (!isActionTaskFinished()) { - LOGGER.warn("wait for lock"); actionTaskLock.wait(timeoutSplitter.getTime()); - LOGGER.warn("continue"); } } } @@ -537,7 +533,9 @@ public Future cancel() { try { unit.reschedule(); } catch (CouldNotPerformException ex) { - // if the reschedule is not possible because of a system shutdown everything is fine, otherwise it s s a controller error and there is no need to inform the remote about any error if the cancellation was successful. + // if the reschedule is not possible because of a system shutdown everything is fine, + // otherwise it is a controller error and there is no need to inform the remote about + // any error if the cancellation was successful. if (!ExceptionProcessor.isCausedBySystemShutdown(ex)) { ExceptionPrinter.printHistory("Reschedule of " + unit + " failed after action cancellation!", ex, LOGGER); } @@ -723,11 +721,7 @@ private void cancelActionTask() { // cancel if exist if (actionTask != null) { - LOGGER.warn("[" +myId+"]"+" cancel["+actionTask.isDone()+"] and interrupt "+ actionTask.hashCode()); actionTask.cancel(true); - LOGGER.warn("interrupted hopefully"); - } else { - LOGGER.warn("[" +myId+"]"+" no interruption performed"); } try { @@ -741,13 +735,12 @@ private void cancelActionTask() { // check if finished after force if (!isActionTaskFinished()) { - LOGGER.error("[" +myId+"]"+" Can not cancel " + this + " it seems the execution has stuck."); StackTracePrinter.printAllStackTraces(null, ActionImpl.class, LOGGER, LogLevel.WARN); StackTracePrinter.detectDeadLocksAndPrintStackTraces(LOGGER); } } - private void updateActionStateIfNotCanceled(final ActionState.State state) throws InterruptedException { + private void updateActionStateIfNotTerminating(final ActionState.State state) throws InterruptedException { synchronized (actionTaskLock) { if (isTerminating()) { throw new InterruptedException(); @@ -756,8 +749,6 @@ private void updateActionStateIfNotCanceled(final ActionState.State state) throw updateActionState(state); } - - private void updateActionStateWhileHoldingWriteLock(final ActionState.State state) { if (!actionDescriptionBuilderLock.isAnyWriteLockHeldByCurrentThread()) { new FatalImplementationErrorException("Update Action description while not holding the action description write lock!", this); @@ -770,14 +761,9 @@ private void updateActionStateWhileHoldingWriteLock(final ActionState.State stat } } - private String myId = ""; - private void updateActionState(final ActionState.State state) throws InterruptedException { actionDescriptionBuilderLock.lockWriteInterruptibly(); try { - - myId = getActionDescription().getActionId() + " - " + MultiLanguageTextProcessor.getBestMatch(getActionDescription().getDescription(), "?"); - // duplicated state confirmation should be ok to simplify the code, but than skip the update. if (getActionState() == state) { return; @@ -815,10 +801,10 @@ private void updateActionState(final ActionState.State state) throws Interrupted } // print update in debug mode -// if (JPService.debugMode()) { + if (JPService.debugMode()) { LOGGER.info("State[" + state.name() + "] " + this); //StackTracePrinter.printStackTrace(LOGGER, LogLevel.INFO); -// } + } // perform the update actionDescriptionBuilder.getActionStateBuilder().setValue(state); @@ -847,7 +833,6 @@ private void updateActionState(final ActionState.State state) throws Interrupted } } - private void validateStateTransition(final ActionState.State state) throws InvalidStateException { // validate state transition switch (getActionState()) { diff --git a/module/dal/control/src/main/java/org/openbase/bco/dal/control/layer/unit/AbstractUnitController.java b/module/dal/control/src/main/java/org/openbase/bco/dal/control/layer/unit/AbstractUnitController.java index 703a7bc53a..7ecf047ea1 100644 --- a/module/dal/control/src/main/java/org/openbase/bco/dal/control/layer/unit/AbstractUnitController.java +++ b/module/dal/control/src/main/java/org/openbase/bco/dal/control/layer/unit/AbstractUnitController.java @@ -1369,22 +1369,10 @@ public void shutdown() { @Override public void applyDataUpdate(Message newState, final ServiceType serviceType) throws CouldNotPerformException { try { - logger.error("wait for lock..."); -// if (!builderSetup.tryLockWrite(5, TimeUnit.SECONDS, this)) { -// throw new InvalidStateException("Unit seems to be stuck!"); -// } - - while (!builderSetup.tryLockWrite(100, TimeUnit.MILLISECONDS, this)) { - - if(Thread.currentThread().isInterrupted()) { - throw new InterruptedException(); - } - - logger.warn("stucked"); + if (!builderSetup.tryLockWrite(5, TimeUnit.SECONDS, this)) { + throw new InvalidStateException("Unit seems to be stuck!"); } - - // builder write unlock block try { try (ClosableDataBuilder dataBuilder = getDataBuilderInterruptible(this)) { @@ -1443,11 +1431,9 @@ public void applyDataUpdate(Message newState, final ServiceType serviceType) thr builderSetup.unlockWrite(NotificationStrategy.AFTER_LAST_RELEASE); } } catch (InterruptedException ex) { - logger.error("recover interruption"); Thread.currentThread().interrupt(); throw new CouldNotPerformException("Update was interrupted!",ex); - } catch (Throwable ex) { - logger.error("Failed"); + } catch (Exception ex) { throw new CouldNotPerformException("Could not apply Service[" + serviceType.name() + "] Update[" + newState + "] for " + this + "!", ex); } } diff --git a/module/registry/unit-registry/lib/src/main/java/org/openbase/bco/registry/unit/lib/filter/UnitConfigFilterImpl.java b/module/registry/unit-registry/lib/src/main/java/org/openbase/bco/registry/unit/lib/filter/UnitConfigFilterImpl.java index 2e70fc1473..66801f7cad 100644 --- a/module/registry/unit-registry/lib/src/main/java/org/openbase/bco/registry/unit/lib/filter/UnitConfigFilterImpl.java +++ b/module/registry/unit-registry/lib/src/main/java/org/openbase/bco/registry/unit/lib/filter/UnitConfigFilterImpl.java @@ -104,7 +104,7 @@ private boolean propertyMatch(final UnitConfig unitConfig) { } // filter by username - if (properties.hasUserConfig() && unitConfig.hasUserConfig() && !(properties.getUserConfig().getUserName().equals(unitConfig.getUserConfig().getUserName()))) { + if (properties.hasUserConfig() && unitConfig.hasUserConfig() && !(properties.getUserConfig().getUserName().equalsIgnoreCase(unitConfig.getUserConfig().getUserName()))) { return false; } diff --git a/module/registry/unit-registry/test/src/test/java/org/openbase/bco/registry/unit/test/UnitConfigFilterTest.kt b/module/registry/unit-registry/test/src/test/java/org/openbase/bco/registry/unit/test/UnitConfigFilterTest.kt index 964f712096..5d39d6facf 100644 --- a/module/registry/unit-registry/test/src/test/java/org/openbase/bco/registry/unit/test/UnitConfigFilterTest.kt +++ b/module/registry/unit-registry/test/src/test/java/org/openbase/bco/registry/unit/test/UnitConfigFilterTest.kt @@ -9,20 +9,70 @@ import org.openbase.type.domotic.unit.UnitFilterType.UnitFilter class UnitConfigFilterTest { @Test - fun `test filter for username`() { + fun `test filter for username with exact cases`() { val username1 = "Guybrush" val username2 = "LeChuck" - val userGuybrush = UnitConfig.newBuilder() - userGuybrush.userConfigBuilder.userName = username1 - val userLeChuck = UnitConfig.newBuilder() - userLeChuck.userConfigBuilder.userName = username2 + val userGuybrush = UnitConfig + .newBuilder() + .also { it.userConfigBuilder.userName = username1 } + .build() - val filterConfig = UnitFilter.newBuilder() - filterConfig.propertiesBuilder.userConfigBuilder.userName = username1 - val guybrushFilter = UnitConfigFilterImpl(filterConfig.build()) + val userLeChuck = UnitConfig + .newBuilder() + .also { it.userConfigBuilder.userName = username2 } + .build() - guybrushFilter.match(userGuybrush.build()) shouldBe true - guybrushFilter.match(userLeChuck.build()) shouldBe false + val guybrushFilter = UnitFilter + .newBuilder() + .also { it.propertiesBuilder.userConfigBuilder.userName = username1 } + .build() + .let { UnitConfigFilterImpl(it) } + + val lechuckFilter = UnitFilter + .newBuilder() + .also {it.propertiesBuilder.userConfigBuilder.userName = username1 } + .build() + .let { UnitConfigFilterImpl(it) } + + guybrushFilter.match(userGuybrush) shouldBe true + guybrushFilter.match(userLeChuck) shouldBe false + + lechuckFilter.match(userGuybrush) shouldBe true + lechuckFilter.match(userLeChuck) shouldBe false + } + + @Test + fun `test filter for username with alternating cases`() { + val username1 = "Guybrush" + val username2 = "LeChuck" + + val userGuybrush = UnitConfig + .newBuilder() + .also { it.userConfigBuilder.userName = username1.uppercase() } + .build() + + val userLeChuck = UnitConfig + .newBuilder() + .also { it.userConfigBuilder.userName = username2.lowercase() } + .build() + + val guybrushFilter = UnitFilter + .newBuilder() + .also { it.propertiesBuilder.userConfigBuilder.userName = username1 } + .build() + .let { UnitConfigFilterImpl(it) } + + val lechuckFilter = UnitFilter + .newBuilder() + .also {it.propertiesBuilder.userConfigBuilder.userName = username1 } + .build() + .let { UnitConfigFilterImpl(it) } + + guybrushFilter.match(userGuybrush) shouldBe true + guybrushFilter.match(userLeChuck) shouldBe false + + lechuckFilter.match(userGuybrush) shouldBe true + lechuckFilter.match(userLeChuck) shouldBe false } } From c5bfb04b5fcace77970f7ad7e4b42c8f756f45bc Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Sat, 26 Nov 2022 19:03:33 +0100 Subject: [PATCH 4/5] update jul --- lib/jul | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jul b/lib/jul index d1dd2405e9..d6d22355e7 160000 --- a/lib/jul +++ b/lib/jul @@ -1 +1 @@ -Subproject commit d1dd2405e995667dee725cc0807f9760d511c416 +Subproject commit d6d22355e7a504ff28762f5550de782d32957932 From b23b1fe9cfb679537977f757c3d269c9ac2c850d Mon Sep 17 00:00:00 2001 From: lhuxohl <51854721+lhuxohl@users.noreply.github.com> Date: Tue, 29 Nov 2022 21:38:10 +0100 Subject: [PATCH 5/5] Update module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java --- .../java/org/openbase/bco/dal/control/action/ActionImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java b/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java index 8436603a67..da8f39c2a1 100644 --- a/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java +++ b/module/dal/control/src/main/java/org/openbase/bco/dal/control/action/ActionImpl.java @@ -735,6 +735,7 @@ private void cancelActionTask() { // check if finished after force if (!isActionTaskFinished()) { + LOGGER.error("Can not finalize " + this + " it seems the execution has stuck."); StackTracePrinter.printAllStackTraces(null, ActionImpl.class, LOGGER, LogLevel.WARN); StackTracePrinter.detectDeadLocksAndPrintStackTraces(LOGGER); }