Changeset 18598 in josm


Ignore:
Timestamp:
2022-11-16T01:08:37+01:00 (18 months ago)
Author:
taylor.smock
Message:

FlatLaf uses properties files which occasionally have breaking changes

In the event that a properties file is misconfigured, FlatLaf will throw
an IllegalArgumentException, which causes JOSM to exit, which is not ideal,
since recovering is not intuitive.

This will roll back the LAF to the platform default, so people can start JOSM.
Which isn't ideal, but is better than not starting indefinitely.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/MainApplication.java

    r18570 r18598  
    11231123    }
    11241124
     1125    /**
     1126     * Set up the UI manager
     1127     */
     1128    // We want to catch all exceptions here to reset LaF to defaults and report it.
     1129    @SuppressWarnings("squid:S2221")
    11251130    static void setupUIManager() {
    11261131        String defaultlaf = PlatformManager.getPlatform().getDefaultStyle();
     
    11491154                    LafPreference.LAF.put(defaultlaf);
    11501155                    Logging.trace(ex);
     1156                } catch (Exception ex) {
     1157                    // We do not want to silently exit if there is an exception.
     1158                    // Put the default laf in place so that the user can use JOSM.
     1159                    LafPreference.LAF.put(defaultlaf);
     1160                    BugReportExceptionHandler.handleException(ex);
    11511161                }
    11521162            } else {
     
    11601170        } catch (InstantiationException | IllegalAccessException e) {
    11611171            Logging.error(e);
     1172        } catch (Exception e) {
     1173            // We do not want to silently exit if there is an exception.
     1174            // Put the default laf in place.
     1175            LafPreference.LAF.put(defaultlaf);
     1176            BugReportExceptionHandler.handleException(e);
    11621177        }
    11631178
  • trunk/test/unit/org/openstreetmap/josm/gui/MainApplicationTest.java

    r17687 r18598  
    22package org.openstreetmap.josm.gui;
    33
     4import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
    45import static org.junit.jupiter.api.Assertions.assertEquals;
    56import static org.junit.jupiter.api.Assertions.assertFalse;
     
    1516import java.io.PrintStream;
    1617import java.net.MalformedURLException;
     18import java.net.URL;
    1719import java.nio.charset.StandardCharsets;
    1820import java.nio.file.Paths;
    1921import java.util.Arrays;
    2022import java.util.Collection;
     23import java.util.Collections;
    2124import java.util.List;
    2225import java.util.concurrent.ExecutionException;
    2326import java.util.concurrent.Future;
     27import java.util.concurrent.atomic.AtomicReference;
    2428import java.util.jar.Attributes;
    2529
    2630import javax.swing.JComponent;
    2731import javax.swing.JPanel;
     32import javax.swing.UIDefaults;
    2833import javax.swing.UIManager;
    29 
     34import javax.swing.plaf.metal.MetalLookAndFeel;
     35
     36import mockit.Mock;
     37import mockit.MockUp;
    3038import org.junit.jupiter.api.Test;
    3139import org.junit.jupiter.api.extension.RegisterExtension;
     
    3846import org.openstreetmap.josm.gui.layer.GpxLayer;
    3947import org.openstreetmap.josm.gui.preferences.ToolbarPreferences;
     48import org.openstreetmap.josm.gui.preferences.display.LafPreference;
     49import org.openstreetmap.josm.plugins.PluginClassLoader;
    4050import org.openstreetmap.josm.plugins.PluginHandler;
    4151import org.openstreetmap.josm.plugins.PluginHandlerTestIT;
     
    5060
    5161import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
     62import org.openstreetmap.josm.tools.bugreport.BugReportQueue;
    5263
    5364/**
     
    196207    @Test
    197208    void testSetupUIManager() {
     209        TestUtils.assumeWorkingJMockit();
    198210        assumeFalse(PlatformManager.isPlatformWindows() && "True".equals(System.getenv("APPVEYOR")));
    199         MainApplication.setupUIManager();
     211        assertDoesNotThrow(MainApplication::setupUIManager);
    200212        assertEquals(Config.getPref().get("laf", PlatformManager.getPlatform().getDefaultStyle()),
    201213                UIManager.getLookAndFeel().getClass().getCanonicalName());
     214        try {
     215            LafPreference.LAF.put(BadLaf.class.getName());
     216            new PluginHandlerMock();
     217            AtomicReference<Throwable> exceptionAtomicReference = new AtomicReference<>();
     218            BugReportQueue.getInstance().setBugReportHandler((e, index) -> {
     219                exceptionAtomicReference.set(e.getCause());
     220                return BugReportQueue.SuppressionMode.NONE;
     221            });
     222            assertDoesNotThrow(MainApplication::setupUIManager);
     223
     224            assertNotNull(exceptionAtomicReference.get());
     225            assertTrue(exceptionAtomicReference.get() instanceof UnsupportedOperationException);
     226            // The LAF only resets on restart, so don't bother checking that it switched back in UIManager
     227            assertEquals(LafPreference.LAF.getDefaultValue(), LafPreference.LAF.get());
     228        } finally {
     229            BugReportQueue.getInstance().setBugReportHandler(BugReportQueue.FALLBACK_BUGREPORT_HANDLER);
     230            // Make certain we reset the LAF
     231            LafPreference.LAF.remove();
     232            assertDoesNotThrow(MainApplication::setupUIManager);
     233            assertEquals(Config.getPref().get("laf", PlatformManager.getPlatform().getDefaultStyle()),
     234                    UIManager.getLookAndFeel().getClass().getCanonicalName());
     235        }
    202236    }
    203237
     
    317351        TestUtils.superficialEnumCodeCoverage(DownloadParamType.class);
    318352    }
     353
     354    /**
     355     * This class exists to test a failure in non-default UI loading
     356     */
     357    public static class BadLaf extends MetalLookAndFeel {
     358        @Override
     359        public UIDefaults getDefaults() {
     360            throw new UnsupportedOperationException("Test failure loading");
     361        }
     362    }
     363
     364    /**
     365     * A mock class for returning a fake plugin class loader for {@link #testSetupUIManager()}
     366     */
     367    public static class PluginHandlerMock extends MockUp<PluginHandler> {
     368        @Mock
     369        public static Collection<PluginClassLoader> getPluginClassLoaders() {
     370            return Collections.singleton(new PluginClassLoader(new URL[0], BadLaf.class.getClassLoader(), Collections.emptyList()));
     371        }
     372    }
    319373}
Note: See TracChangeset for help on using the changeset viewer.