From 57b850ab682472fd3724c9a2715bb1103a407a68 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Tue, 12 Dec 2023 21:27:35 +0100 Subject: [PATCH 1/8] Improve error logging of RPCServer. --- .../org/openbase/jul/communication/mqtt/RPCServerImpl.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/module/communication/mqtt/src/main/java/org/openbase/jul/communication/mqtt/RPCServerImpl.kt b/module/communication/mqtt/src/main/java/org/openbase/jul/communication/mqtt/RPCServerImpl.kt index 138d8717d..5405abe1e 100644 --- a/module/communication/mqtt/src/main/java/org/openbase/jul/communication/mqtt/RPCServerImpl.kt +++ b/module/communication/mqtt/src/main/java/org/openbase/jul/communication/mqtt/RPCServerImpl.kt @@ -6,6 +6,7 @@ import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5Publish import com.hivemq.client.mqtt.mqtt5.message.subscribe.Mqtt5Subscribe import com.hivemq.client.mqtt.mqtt5.message.unsubscribe.Mqtt5Unsubscribe import kotlinx.coroutines.* +import org.openbase.jps.core.JPService import org.openbase.jul.annotation.RPCMethod import org.openbase.jul.communication.config.CommunicatorConfig import org.openbase.jul.communication.iface.RPCServer @@ -158,8 +159,12 @@ class RPCServerImpl( responseBuilder.result = result } catch (ex: Exception) { when (ex) { - is InvocationTargetException -> responseBuilder.error = - ex.cause?.stackTraceToString() ?: ex.stackTraceToString() + is InvocationTargetException -> { + if (JPService.verboseMode()) { + ExceptionPrinter.printHistory(ex, logger, LogLevel.WARN) + } + responseBuilder.error = ex.cause?.stackTraceToString() ?: ex.stackTraceToString() + } else -> { ExceptionPrinter.printHistory(ex, logger, LogLevel.WARN) From 884535a153d73777d7c791559634fc09d7c91b76 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Tue, 12 Dec 2023 21:28:22 +0100 Subject: [PATCH 2/8] Make sure FatalImpl Exception print their message in unit tests. --- .../exception/printer/ExceptionPrinter.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/module/exception/src/main/java/org/openbase/jul/exception/printer/ExceptionPrinter.java b/module/exception/src/main/java/org/openbase/jul/exception/printer/ExceptionPrinter.java index 04cd6d86e..2248ab03d 100644 --- a/module/exception/src/main/java/org/openbase/jul/exception/printer/ExceptionPrinter.java +++ b/module/exception/src/main/java/org/openbase/jul/exception/printer/ExceptionPrinter.java @@ -10,32 +10,35 @@ * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Lesser Public License for more details. - * + * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * . * #L% */ -import java.io.PrintStream; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutionException; - import org.openbase.jps.core.JPService; import org.openbase.jps.exception.JPServiceException; import org.openbase.jps.preset.JPLogLevel; import org.openbase.jps.preset.JPVerbose; -import org.openbase.jul.exception.*; +import org.openbase.jul.exception.CouldNotPerformException; +import org.openbase.jul.exception.FatalImplementationErrorException; +import org.openbase.jul.exception.MultiException; import org.openbase.jul.exception.MultiException.SourceExceptionEntry; +import org.openbase.jul.exception.ShutdownInProgressException; import org.slf4j.Logger; +import java.io.PrintStream; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; + /** * @author Divine Threepwood */ @@ -273,7 +276,7 @@ private static void exit(final int errorCode) { System.exit(errorCode); } - throw new RuntimeException(new ShutdownInProgressException("Shutdown with error code "+ errorCode + " initiated!")); + throw new RuntimeException(new ShutdownInProgressException("Shutdown with error code " + errorCode + " initiated!")); } /** @@ -323,7 +326,7 @@ public static void printHistory(final T th, final Printer // throw assertion error in case FatalImplementationErrorException was detected. printer.print(SEPARATOR); printer.print(getContext(th), th); - assert ExceptionPrinter.isQuiet() : "Assert because FatalImplementationException was thrown!"; + assert ExceptionPrinter.isQuiet() : "Assert because FatalImplementationException was thrown: " + th.getMessage(); } else if (printer.isDebugEnabled()) { // Print normal stacktrace in debug mode for all errors. switch (printer.getLogLevel()) { From 06bf412d71d31285886ad8c9559cd572663cbf8c Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Tue, 12 Dec 2023 21:28:54 +0100 Subject: [PATCH 3/8] fix typos --- .../openbase/jul/pattern/AbstractObservable.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/module/pattern/default/src/main/java/org/openbase/jul/pattern/AbstractObservable.java b/module/pattern/default/src/main/java/org/openbase/jul/pattern/AbstractObservable.java index 1dc001e70..84c1b4d0a 100644 --- a/module/pattern/default/src/main/java/org/openbase/jul/pattern/AbstractObservable.java +++ b/module/pattern/default/src/main/java/org/openbase/jul/pattern/AbstractObservable.java @@ -10,12 +10,12 @@ * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Lesser Public License for more details. - * + * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * . @@ -24,16 +24,13 @@ import org.openbase.jul.exception.*; import org.openbase.jul.exception.MultiException.ExceptionStack; -import org.openbase.jul.exception.printer.ExceptionPrinter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; -import java.util.Map.Entry; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.TimeUnit; /** * @param the type of the data source @@ -183,10 +180,10 @@ public void reset() { * source of the notification is set as this. Because of data encapsulation reasons this method * is not included within the Observer interface. * Attention! This method is not thread safe against changes of the observable because the check if the observable has changed is - * done by computing its hash value. Therefore if the observable is a collection and it is changed + * done by computing its hash value. Therefore, if the observable is a collection, and it is changed * while notifying a concurrent modification exception can occur. To avoid this compute the * observable hash yourself by setting a hash generator. - * If this method is interrupted a rollback is done by reseting the latestHashValue. Thus the observable + * If this method is interrupted a rollback is done by resetting the latestHashValue. Thus, the observable * has not changed and false is returned. * * @param observable the value which is notified @@ -205,10 +202,10 @@ public boolean notifyObservers(final T observable) throws MultiException, CouldN * Because of data encapsulation reasons this method is not included within the Observer * interface. * Attention! This method is not thread safe against changes of the observable because the check if the observable has changed is - * done by computing its hash value. Therefore if the observable is a collection and it is changed + * done by computing its hash value. Therefore, if the observable is a collection, and it is changed * while notifying a concurrent modification exception can occur. To avoid this compute the * observable hash yourself by setting a hash generator. - * If this method is interrupted a rollback is done by reseting the latestHashValue. Thus the observable + * If this method is interrupted a rollback is done by resetting the latestHashValue. Thus, the observable * has not changed and false is returned. *

* Note: In case the given observable is null this notification will be ignored. From be3f9feb344c10937bf6032c396e3161de3f40b5 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Tue, 12 Dec 2023 21:29:11 +0100 Subject: [PATCH 4/8] format code --- .../org/openbase/jul/schedule/RecurrenceEventFilter.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/module/schedule/src/main/java/org/openbase/jul/schedule/RecurrenceEventFilter.java b/module/schedule/src/main/java/org/openbase/jul/schedule/RecurrenceEventFilter.java index d80f4a064..317eb93c5 100644 --- a/module/schedule/src/main/java/org/openbase/jul/schedule/RecurrenceEventFilter.java +++ b/module/schedule/src/main/java/org/openbase/jul/schedule/RecurrenceEventFilter.java @@ -10,12 +10,12 @@ * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Lesser Public License for more details. - * + * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * . @@ -134,6 +134,7 @@ public void trigger(final boolean immediately) throws CouldNotPerformException { * * @param value the new value which should be published via the next relay. * @param immediately this flag forces the trigger to relay immediately without respect to the defined max frequency. + * * @throws CouldNotPerformException is thrown if the trigger could not be handled (e.g. because of a system shutdown). */ public synchronized void trigger(final VALUE value, final boolean immediately) throws CouldNotPerformException { From 204ddc2d1d0ff24a811519cd56fe0fadbf01c44d Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Tue, 12 Dec 2023 21:30:20 +0100 Subject: [PATCH 5/8] Fix concurrent modicitation issue in the FileSynchronizedRegistryImpl by properly locking the fileSynchronizerMap. --- .../FileSynchronizedRegistryImpl.java | 185 +++++++++++++----- 1 file changed, 133 insertions(+), 52 deletions(-) diff --git a/module/storage/src/main/java/org/openbase/jul/storage/registry/FileSynchronizedRegistryImpl.java b/module/storage/src/main/java/org/openbase/jul/storage/registry/FileSynchronizedRegistryImpl.java index 5f84fc3d0..7f3bf9fef 100644 --- a/module/storage/src/main/java/org/openbase/jul/storage/registry/FileSynchronizedRegistryImpl.java +++ b/module/storage/src/main/java/org/openbase/jul/storage/registry/FileSynchronizedRegistryImpl.java @@ -10,12 +10,12 @@ * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Lesser Public License for more details. - * + * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * . @@ -28,8 +28,7 @@ import org.openbase.jps.preset.JPForce; import org.openbase.jps.preset.JPReadOnly; import org.openbase.jps.preset.JPShareDirectory; -import org.openbase.jul.exception.InstantiationException; -import org.openbase.jul.exception.*; +import org.openbase.jul.exception.CouldNotPerformException; import org.openbase.jul.exception.MultiException.ExceptionStack; import org.openbase.jul.exception.printer.ExceptionPrinter; import org.openbase.jul.exception.printer.LogLevel; @@ -48,6 +47,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.locks.ReentrantReadWriteLock; /** * @param @@ -60,8 +60,9 @@ public class FileSynchronizedRegistryImpl, MAP extends Map, REGISTRY extends FileSynchronizedRegistry> extends AbstractRegistry> implements FileSynchronizedRegistry { private final File databaseDirectory; - // release todo: synchronize fileSynchronizerMap because otherwise sometimes occure concurrent modification exceptions. Use a lock not synchronize block to make parallel read access more reliable. Validate that the new lock does not cause into deadlocks because of the registry sync. private final Map> fileSynchronizerMap; + + private final ReentrantReadWriteLock fileSynchronizerMapLock = new ReentrantReadWriteLock(); private final FileProcessor fileProcessor; private final FileProvider> fileProvider; @@ -152,51 +153,90 @@ public void activateVersionControl(final String entryType, final Package convert @Override public ENTRY register(final ENTRY entry) throws CouldNotPerformException { - ENTRY result = super.register(entry); - FileSynchronizer fileSynchronizer = new FileSynchronizer<>(result, new File(databaseDirectory, fileProvider.getFileName(entry)), FileSynchronizer.InitMode.CREATE, fileProcessor); - fileSynchronizerMap.put(result.getId(), fileSynchronizer); - filePluginPool.afterRegister(result, fileSynchronizer); - - return result; + try { + fileSynchronizerMapLock.writeLock().lockInterruptibly(); + try { + ENTRY result = super.register(entry); + FileSynchronizer fileSynchronizer = new FileSynchronizer<>(result, new File(databaseDirectory, fileProvider.getFileName(entry)), FileSynchronizer.InitMode.CREATE, fileProcessor); + fileSynchronizerMap.put(result.getId(), fileSynchronizer); + filePluginPool.afterRegister(result, fileSynchronizer); + return result; + } finally { + fileSynchronizerMapLock.writeLock().unlock(); + } + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + throw new RuntimeException(ex); + } } @Override public ENTRY update(final ENTRY entry) throws CouldNotPerformException { - ENTRY result = super.update(entry); + try { + fileSynchronizerMapLock.readLock().lockInterruptibly(); + try { + ENTRY result = super.update(entry); - // ignore update during registration process. - if (!fileSynchronizerMap.containsKey(result.getId())) { - logger.debug("Ignore update during registration process of entry " + result); - return entry; - } + // ignore update during registration process. + if (!fileSynchronizerMap.containsKey(result.getId())) { + logger.debug("Ignore update during registration process of entry " + result); + return entry; + } - FileSynchronizer fileSynchronizer = fileSynchronizerMap.get(result.getId()); + FileSynchronizer fileSynchronizer = fileSynchronizerMap.get(result.getId()); - filePluginPool.beforeUpdate(result, fileSynchronizer); - fileSynchronizer.save(result); - filePluginPool.afterUpdate(result, fileSynchronizer); + filePluginPool.beforeUpdate(result, fileSynchronizer); + fileSynchronizer.save(result); + filePluginPool.afterUpdate(result, fileSynchronizer); - return result; + return result; + } finally { + fileSynchronizerMapLock.readLock().unlock(); + } + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + throw new RuntimeException(ex); + } } @Override public ENTRY remove(final ENTRY entry) throws CouldNotPerformException { - ENTRY removedValue = super.remove(entry); + try { + fileSynchronizerMapLock.writeLock().lockInterruptibly(); + try { + ENTRY removedValue = super.remove(entry); - FileSynchronizer fileSynchronizer = fileSynchronizerMap.get(entry.getId()); + FileSynchronizer fileSynchronizer = fileSynchronizerMap.get(entry.getId()); - filePluginPool.beforeRemove(entry, fileSynchronizer); - fileSynchronizer.delete(); - fileSynchronizerMap.remove(entry.getId()); - filePluginPool.afterRemove(entry, fileSynchronizer); + filePluginPool.beforeRemove(entry, fileSynchronizer); + fileSynchronizer.delete(); + fileSynchronizerMap.remove(entry.getId()); + filePluginPool.afterRemove(entry, fileSynchronizer); - return removedValue; + return removedValue; + } finally { + fileSynchronizerMapLock.writeLock().unlock(); + } + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + throw new RuntimeException(ex); + } } @Override public void clear() throws CouldNotPerformException { super.clear(); - fileSynchronizerMap.clear(); + try { + fileSynchronizerMapLock.writeLock().lockInterruptibly(); + try { + fileSynchronizerMap.clear(); + } finally { + fileSynchronizerMapLock.writeLock().unlock(); + } + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + throw new RuntimeException(ex); + } } @Override @@ -267,10 +307,20 @@ public void loadRegistry() throws CouldNotPerformException { } // init file synchronizer - FileSynchronizer fileSynchronizer = new FileSynchronizer<>(file, fileProcessor); - ENTRY entry = fileSynchronizer.getData(); - fileSynchronizerMap.put(entry.getId(), fileSynchronizer); - super.load(entry); + try { + fileSynchronizerMapLock.writeLock().lockInterruptibly(); + try { + FileSynchronizer fileSynchronizer = new FileSynchronizer<>(file, fileProcessor); + ENTRY entry = fileSynchronizer.getData(); + fileSynchronizerMap.put(entry.getId(), fileSynchronizer); + super.load(entry); + } finally { + fileSynchronizerMapLock.writeLock().unlock(); + } + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + throw new RuntimeException(ex); + } } catch (CouldNotPerformException ex) { exceptionStack = MultiException.push(this, ex, exceptionStack); } @@ -307,12 +357,22 @@ public synchronized void saveRegistry() throws MultiException { ExceptionStack exceptionStack = null; // save all changes. - for (FileSynchronizer fileSynchronizer : new ArrayList<>(fileSynchronizerMap.values())) { + try { + fileSynchronizerMapLock.readLock().lockInterruptibly(); try { - fileSynchronizer.save(); - } catch (CouldNotPerformException ex) { - exceptionStack = MultiException.push(this, ex, exceptionStack); + for (FileSynchronizer fileSynchronizer : new ArrayList<>(fileSynchronizerMap.values())) { + try { + fileSynchronizer.save(); + } catch (CouldNotPerformException ex) { + exceptionStack = MultiException.push(this, ex, exceptionStack); + } + } + } finally { + fileSynchronizerMapLock.readLock().unlock(); } + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + throw new RuntimeException(ex); } // verify and apply file name changes @@ -321,26 +381,37 @@ public synchronized void saveRegistry() throws MultiException { FileSynchronizer newFileSynchronizer; File newFile; - for (Entry> entry : new ArrayList<>(fileSynchronizerMap.entrySet())) { - fileSynchronizer = entry.getValue(); + + try { + fileSynchronizerMapLock.writeLock().lockInterruptibly(); try { - generatedFileName = fileProvider.getFileName(fileSynchronizer.getData()); - if (!fileSynchronizer.getFile().getName().equals(generatedFileName)) { + for (Entry> entry : new ArrayList<>(fileSynchronizerMap.entrySet())) { + fileSynchronizer = entry.getValue(); try { - // rename file - newFile = new File(fileSynchronizer.getFile().getParent(), generatedFileName); - if (!fileSynchronizer.getFile().renameTo(newFile)) { - throw new CouldNotPerformException("Rename failed without explicit error code, please rename file manually after registry shutdown!"); + generatedFileName = fileProvider.getFileName(fileSynchronizer.getData()); + if (!fileSynchronizer.getFile().getName().equals(generatedFileName)) { + try { + // rename file + newFile = new File(fileSynchronizer.getFile().getParent(), generatedFileName); + if (!fileSynchronizer.getFile().renameTo(newFile)) { + throw new CouldNotPerformException("Rename failed without explicit error code, please rename file manually after registry shutdown!"); + } + newFileSynchronizer = new FileSynchronizer<>(fileSynchronizer.getData(), newFile, FileSynchronizer.InitMode.AUTO, fileProcessor); + fileSynchronizerMap.replace(entry.getKey(), fileSynchronizer, newFileSynchronizer); + } catch (CouldNotPerformException ex) { + exceptionStack = MultiException.push(this, new CouldNotPerformException("Could not apply db Entry[" + fileSynchronizer.getFile().getName() + "] renaming to Entry[" + generatedFileName + "]!", ex), exceptionStack); + } } - newFileSynchronizer = new FileSynchronizer<>(fileSynchronizer.getData(), newFile, FileSynchronizer.InitMode.AUTO, fileProcessor); - fileSynchronizerMap.replace(entry.getKey(), fileSynchronizer, newFileSynchronizer); } catch (CouldNotPerformException ex) { - exceptionStack = MultiException.push(this, new CouldNotPerformException("Could not apply db Entry[" + fileSynchronizer.getFile().getName() + "] renaming to Entry[" + generatedFileName + "]!", ex), exceptionStack); + exceptionStack = MultiException.push(this, new CouldNotPerformException("Could not reconstruct filename of db Entry[" + fileSynchronizer.getFile().getName() + "]!", ex), exceptionStack); } } - } catch (CouldNotPerformException ex) { - exceptionStack = MultiException.push(this, new CouldNotPerformException("Could not reconstruct filename of db Entry[" + fileSynchronizer.getFile().getName() + "]!", ex), exceptionStack); + } finally { + fileSynchronizerMapLock.writeLock().unlock(); } + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + throw new RuntimeException(ex); } MultiException.checkAndThrow(() -> "Could not save all registry entries!", exceptionStack); @@ -389,7 +460,17 @@ public void shutdown() { ExceptionPrinter.printHistory(new CouldNotPerformException("Final save failed!", ex), logger); } - fileSynchronizerMap.clear(); + try { + fileSynchronizerMapLock.writeLock().lockInterruptibly(); + try { + fileSynchronizerMap.clear(); + } finally { + fileSynchronizerMapLock.writeLock().unlock(); + } + } catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + throw new RuntimeException(ex); + } super.shutdown(); } From 5ce4d40d26763f2f03005008bf8ad37986c8f648 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Tue, 12 Dec 2023 21:31:06 +0100 Subject: [PATCH 6/8] Improve logging in case bco starts in offline mode. --- .../registry/version/GitVersionControl.java | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/module/storage/src/main/java/org/openbase/jul/storage/registry/version/GitVersionControl.java b/module/storage/src/main/java/org/openbase/jul/storage/registry/version/GitVersionControl.java index 71069915b..eeeba90bf 100644 --- a/module/storage/src/main/java/org/openbase/jul/storage/registry/version/GitVersionControl.java +++ b/module/storage/src/main/java/org/openbase/jul/storage/registry/version/GitVersionControl.java @@ -10,12 +10,12 @@ * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Lesser Public License for more details. - * + * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * . @@ -31,6 +31,7 @@ import org.eclipse.jgit.lib.Ref; import org.openbase.jps.core.JPService; import org.openbase.jul.exception.CouldNotPerformException; +import org.openbase.jul.exception.ExceptionProcessor; import org.openbase.jul.exception.printer.ExceptionPrinter; import org.openbase.jul.exception.printer.LogLevel; import org.openbase.jul.storage.registry.FileSynchronizedRegistry; @@ -39,10 +40,9 @@ import org.slf4j.LoggerFactory; import java.io.IOException; -import java.util.Collections; +import java.net.UnknownHostException; /** - * * This tool class can be used to handle automated update and compatibility handling of external registry dbs. * * @author Divine Threepwood // @@ -60,7 +60,7 @@ public class GitVersionControl { public static void syncWithRemoteDatabase(final int latestSupportedDBVersion, final FileSynchronizedRegistry registry) throws CouldNotPerformException { - try(final Git registryDBGit = Git.open(registry.getDatabaseDirectory())) { + try (final Git registryDBGit = Git.open(registry.getDatabaseDirectory())) { // reset current database state before triggering the remote sync if repo is valid. if (registryDBGit.getRepository() != null && registryDBGit.getRepository().getFullBranch() != null) { @@ -70,9 +70,9 @@ public static void syncWithRemoteDatabase(final int latestSupportedDBVersion, fi if (!currentBranchName.equals(MASTER_BRANCH_LOCAL_IDENTIFIER) && !currentBranchName.startsWith(RELEASE_BRANCH_LOCAL_PREFIX)) { if (registryDBGit.status().call().isClean()) { // sync with remote repo - logger.warn("Custom " + registry + " branch "+currentBranchName+" detected, remote sync will be performed but db auto upgrade will be skipped..."); + logger.warn("Custom " + registry + " branch " + currentBranchName + " detected, remote sync will be performed but db auto upgrade will be skipped..."); try { - if(!registryDBGit.pull().call().isSuccessful()) { + if (!registryDBGit.pull().call().isSuccessful()) { throw new CouldNotPerformException("Pull was not successful!"); } } catch (GitAPIException | CouldNotPerformException ex) { @@ -88,7 +88,7 @@ public static void syncWithRemoteDatabase(final int latestSupportedDBVersion, fi registryDBGit.reset().setMode(ResetType.HARD).call(); registryDBGit.clean().setForce(true).call(); } else { - logger.info("Perform initial sync with remote database of "+ registry.getName()+ "..."); + logger.info("Perform initial sync with remote database of " + registry.getName() + "..."); } // sync branches with remote repo @@ -96,17 +96,16 @@ public static void syncWithRemoteDatabase(final int latestSupportedDBVersion, fi try { registryDBGit.fetch().call(); } catch (GitAPIException ex) { - final String errorMessage = "Could not sync with remote repository of " + registry.getName() + " and continue in offline mode..."; - if(JPService.verboseMode()) { - ExceptionPrinter.printHistory(errorMessage, ex, logger, LogLevel.WARN); + if (ExceptionProcessor.getInitialCause(ex) instanceof UnknownHostException) { + offline = true; + logger.info("Could not sync with remote repository of " + registry.getName() + " and continue in offline mode..."); } else { - logger.warn(errorMessage); + throw ex; } - offline = true; } // checkout latest compatible database - if(JPService.getValue(JPDeveloperMode.class, false)) { + if (JPService.getValue(JPDeveloperMode.class, false)) { // lookup local branch boolean localBranchExist = false; @@ -129,11 +128,11 @@ public static void syncWithRemoteDatabase(final int latestSupportedDBVersion, fi int repositoryDBReleaseVersion = 0; for (Ref ref : registryDBGit.branchList().setListMode(ListMode.REMOTE).call()) { final String branchName = ref.getName(); - if(branchName.startsWith(RELEASE_BRANCH_REMOTE_PREFIX)) { + if (branchName.startsWith(RELEASE_BRANCH_REMOTE_PREFIX)) { try { repositoryDBReleaseVersion = Math.max(repositoryDBReleaseVersion, Integer.parseInt(branchName.substring(RELEASE_BRANCH_REMOTE_PREFIX.length()))); } catch (NumberFormatException ex) { - logger.warn(registry.getName() + " remote database contains an invalid release branch["+branchName+"]! Those will be skipped..."); + logger.warn(registry.getName() + " remote database contains an invalid release branch[" + branchName + "]! Those will be skipped..."); } } } @@ -165,12 +164,12 @@ public static void syncWithRemoteDatabase(final int latestSupportedDBVersion, fi registryDBGit.pull().call(); } catch (final TransportException ex) { // skip offline warnings. - if(!offline) { + if (!offline) { throw ex; } } } catch (GitAPIException | CouldNotPerformException | IOException ex) { - throw new CouldNotPerformException("Auto db update of "+ registry.getName()+" failed!", ex); + throw new CouldNotPerformException("Auto db update of " + registry.getName() + " failed!", ex); } } } From e085a56b980e9aeaab1ed899295a6d57497fa201 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Tue, 12 Dec 2023 21:45:29 +0100 Subject: [PATCH 7/8] fix imports --- .../jul/storage/registry/FileSynchronizedRegistryImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/module/storage/src/main/java/org/openbase/jul/storage/registry/FileSynchronizedRegistryImpl.java b/module/storage/src/main/java/org/openbase/jul/storage/registry/FileSynchronizedRegistryImpl.java index 7f3bf9fef..43fbb9527 100644 --- a/module/storage/src/main/java/org/openbase/jul/storage/registry/FileSynchronizedRegistryImpl.java +++ b/module/storage/src/main/java/org/openbase/jul/storage/registry/FileSynchronizedRegistryImpl.java @@ -28,7 +28,8 @@ import org.openbase.jps.preset.JPForce; import org.openbase.jps.preset.JPReadOnly; import org.openbase.jps.preset.JPShareDirectory; -import org.openbase.jul.exception.CouldNotPerformException; +import org.openbase.jul.exception.InstantiationException; +import org.openbase.jul.exception.*; import org.openbase.jul.exception.MultiException.ExceptionStack; import org.openbase.jul.exception.printer.ExceptionPrinter; import org.openbase.jul.exception.printer.LogLevel; From c29cdf5059a8d7ec6bf9d5ecedb63a7e0294d2d1 Mon Sep 17 00:00:00 2001 From: Divine Threepwood Date: Tue, 12 Dec 2023 22:13:05 +0100 Subject: [PATCH 8/8] switch java fix to 21 becaues of dependency issues --- module/visual/javafx/build.gradle.kts | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/module/visual/javafx/build.gradle.kts b/module/visual/javafx/build.gradle.kts index 441112f6d..6407fbdcb 100644 --- a/module/visual/javafx/build.gradle.kts +++ b/module/visual/javafx/build.gradle.kts @@ -6,21 +6,21 @@ dependencies { api(project(":jul.interface")) api(project(":jul.extension.type.interface")) api(project(":jul.schedule")) - api("org.openjfx:javafx-base:17.0.9:win") - api("org.openjfx:javafx-fxml:17.0.9:win") - api("org.openjfx:javafx-graphics:17.0.9:win") - api("org.openjfx:javafx-media:17.0.9:win") - api("org.openjfx:javafx-controls:17.0.9:win") - api("org.openjfx:javafx-base:17.0.9:mac") - api("org.openjfx:javafx-fxml:17.0.9:mac") - api("org.openjfx:javafx-graphics:17.0.9:mac") - api("org.openjfx:javafx-media:17.0.9:mac") - api("org.openjfx:javafx-controls:17.0.9:mac") - api("org.openjfx:javafx-base:17.0.9:linux") - api("org.openjfx:javafx-fxml:17.0.9:linux") - api("org.openjfx:javafx-graphics:17.0.9:linux") - api("org.openjfx:javafx-media:17.0.9:linux") - api("org.openjfx:javafx-controls:17.0.9:linux") + api("org.openjfx:javafx-base:21.0.1:win") + api("org.openjfx:javafx-fxml:21.0.1:win") + api("org.openjfx:javafx-graphics:21.0.1:win") + api("org.openjfx:javafx-media:21.0.1:win") + api("org.openjfx:javafx-controls:21.0.1:win") + api("org.openjfx:javafx-base:21.0.1:mac") + api("org.openjfx:javafx-fxml:21.0.1:mac") + api("org.openjfx:javafx-graphics:21.0.1:mac") + api("org.openjfx:javafx-media:21.0.1:mac") + api("org.openjfx:javafx-controls:21.0.1:mac") + api("org.openjfx:javafx-base:21.0.1:linux") + api("org.openjfx:javafx-fxml:21.0.1:linux") + api("org.openjfx:javafx-graphics:21.0.1:linux") + api("org.openjfx:javafx-media:21.0.1:linux") + api("org.openjfx:javafx-controls:21.0.1:linux") api("org.controlsfx:controlsfx:_") api("de.jensd:fontawesomefx:_") api("com.jfoenix:jfoenix:_")