Index: trunk/src/org/openstreetmap/josm/gui/MainApplication.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 18597)
+++ trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 18598)
@@ -1123,4 +1123,9 @@
     }
 
+    /**
+     * Set up the UI manager
+     */
+    // We want to catch all exceptions here to reset LaF to defaults and report it.
+    @SuppressWarnings("squid:S2221")
     static void setupUIManager() {
         String defaultlaf = PlatformManager.getPlatform().getDefaultStyle();
@@ -1149,4 +1154,9 @@
                     LafPreference.LAF.put(defaultlaf);
                     Logging.trace(ex);
+                } catch (Exception ex) {
+                    // We do not want to silently exit if there is an exception.
+                    // Put the default laf in place so that the user can use JOSM.
+                    LafPreference.LAF.put(defaultlaf);
+                    BugReportExceptionHandler.handleException(ex);
                 }
             } else {
@@ -1160,4 +1170,9 @@
         } catch (InstantiationException | IllegalAccessException e) {
             Logging.error(e);
+        } catch (Exception e) {
+            // We do not want to silently exit if there is an exception.
+            // Put the default laf in place.
+            LafPreference.LAF.put(defaultlaf);
+            BugReportExceptionHandler.handleException(e);
         }
 
Index: trunk/test/unit/org/openstreetmap/josm/gui/MainApplicationTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/MainApplicationTest.java	(revision 18597)
+++ trunk/test/unit/org/openstreetmap/josm/gui/MainApplicationTest.java	(revision 18598)
@@ -2,4 +2,5 @@
 package org.openstreetmap.josm.gui;
 
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -15,17 +16,24 @@
 import java.io.PrintStream;
 import java.net.MalformedURLException;
+import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.jar.Attributes;
 
 import javax.swing.JComponent;
 import javax.swing.JPanel;
+import javax.swing.UIDefaults;
 import javax.swing.UIManager;
-
+import javax.swing.plaf.metal.MetalLookAndFeel;
+
+import mockit.Mock;
+import mockit.MockUp;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
@@ -38,4 +46,6 @@
 import org.openstreetmap.josm.gui.layer.GpxLayer;
 import org.openstreetmap.josm.gui.preferences.ToolbarPreferences;
+import org.openstreetmap.josm.gui.preferences.display.LafPreference;
+import org.openstreetmap.josm.plugins.PluginClassLoader;
 import org.openstreetmap.josm.plugins.PluginHandler;
 import org.openstreetmap.josm.plugins.PluginHandlerTestIT;
@@ -50,4 +60,5 @@
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import org.openstreetmap.josm.tools.bugreport.BugReportQueue;
 
 /**
@@ -196,8 +207,31 @@
     @Test
     void testSetupUIManager() {
+        TestUtils.assumeWorkingJMockit();
         assumeFalse(PlatformManager.isPlatformWindows() && "True".equals(System.getenv("APPVEYOR")));
-        MainApplication.setupUIManager();
+        assertDoesNotThrow(MainApplication::setupUIManager);
         assertEquals(Config.getPref().get("laf", PlatformManager.getPlatform().getDefaultStyle()),
                 UIManager.getLookAndFeel().getClass().getCanonicalName());
+        try {
+            LafPreference.LAF.put(BadLaf.class.getName());
+            new PluginHandlerMock();
+            AtomicReference<Throwable> exceptionAtomicReference = new AtomicReference<>();
+            BugReportQueue.getInstance().setBugReportHandler((e, index) -> {
+                exceptionAtomicReference.set(e.getCause());
+                return BugReportQueue.SuppressionMode.NONE;
+            });
+            assertDoesNotThrow(MainApplication::setupUIManager);
+
+            assertNotNull(exceptionAtomicReference.get());
+            assertTrue(exceptionAtomicReference.get() instanceof UnsupportedOperationException);
+            // The LAF only resets on restart, so don't bother checking that it switched back in UIManager
+            assertEquals(LafPreference.LAF.getDefaultValue(), LafPreference.LAF.get());
+        } finally {
+            BugReportQueue.getInstance().setBugReportHandler(BugReportQueue.FALLBACK_BUGREPORT_HANDLER);
+            // Make certain we reset the LAF
+            LafPreference.LAF.remove();
+            assertDoesNotThrow(MainApplication::setupUIManager);
+            assertEquals(Config.getPref().get("laf", PlatformManager.getPlatform().getDefaultStyle()),
+                    UIManager.getLookAndFeel().getClass().getCanonicalName());
+        }
     }
 
@@ -317,3 +351,23 @@
         TestUtils.superficialEnumCodeCoverage(DownloadParamType.class);
     }
+
+    /**
+     * This class exists to test a failure in non-default UI loading
+     */
+    public static class BadLaf extends MetalLookAndFeel {
+        @Override
+        public UIDefaults getDefaults() {
+            throw new UnsupportedOperationException("Test failure loading");
+        }
+    }
+
+    /**
+     * A mock class for returning a fake plugin class loader for {@link #testSetupUIManager()}
+     */
+    public static class PluginHandlerMock extends MockUp<PluginHandler> {
+        @Mock
+        public static Collection<PluginClassLoader> getPluginClassLoaders() {
+            return Collections.singleton(new PluginClassLoader(new URL[0], BadLaf.class.getClassLoader(), Collections.emptyList()));
+        }
+    }
 }
