Index: /trunk/src/org/openstreetmap/josm/gui/MainApplication.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 13355)
+++ /trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 13356)
@@ -156,5 +156,4 @@
 import org.openstreetmap.josm.tools.FontsManager;
 import org.openstreetmap.josm.tools.GBC;
-import org.openstreetmap.josm.tools.HttpClient;
 import org.openstreetmap.josm.tools.I18n;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -955,5 +954,5 @@
             for (String i : args.get(Option.LOAD_PREFERENCES)) {
                 Logging.info("Reading preferences from " + i);
-                try (InputStream is = openStream(new URL(i))) {
+                try (InputStream is = Utils.openStream(new URL(i))) {
                     config.openAndReadXML(is);
                 } catch (IOException ex) {
@@ -1206,12 +1205,4 @@
                 }
             }
-        }
-    }
-
-    private static InputStream openStream(URL url) throws IOException {
-        if ("file".equals(url.getProtocol())) {
-            return url.openStream();
-        } else {
-            return HttpClient.create(url).connect().getContent();
         }
     }
Index: /trunk/src/org/openstreetmap/josm/io/OsmServerReader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 13355)
+++ /trunk/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 13356)
@@ -164,7 +164,8 @@
             }
 
-            if ("file".equals(url.getProtocol())) {
+            String protocol = url.getProtocol();
+            if ("file".equals(protocol) || "jar".equals(protocol)) {
                 try {
-                    return url.openStream();
+                    return Utils.openStream(url);
                 } catch (IOException e) {
                     throw new OsmTransferException(e);
Index: /trunk/src/org/openstreetmap/josm/tools/I18n.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/I18n.java	(revision 13355)
+++ /trunk/src/org/openstreetmap/josm/tools/I18n.java	(revision 13356)
@@ -419,6 +419,6 @@
         }
         try (
-            InputStream enStream = en.openStream();
-            InputStream trStream = tr.openStream()
+            InputStream enStream = Utils.openStream(en);
+            InputStream trStream = Utils.openStream(tr)
         ) {
             if (load(enStream, trStream, false)) {
Index: /trunk/src/org/openstreetmap/josm/tools/ImageProvider.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 13355)
+++ /trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 13356)
@@ -1718,21 +1718,14 @@
         CheckParameterUtil.ensureParameterNotNull(input, "input");
 
-        InputStream istream = null;
-        try {
-            istream = input.openStream();
+        try (InputStream istream = Utils.openStream(input)) {
+            ImageInputStream stream = ImageIO.createImageInputStream(istream);
+            BufferedImage bi = read(stream, readMetadata, enforceTransparency);
+            if (bi == null) {
+                stream.close();
+            }
+            return bi;
         } catch (IOException e) {
             throw new IIOException("Can't get input stream from URL!", e);
         }
-        ImageInputStream stream = ImageIO.createImageInputStream(istream);
-        BufferedImage bi;
-        try {
-            bi = read(stream, readMetadata, enforceTransparency);
-            if (bi == null) {
-                stream.close();
-            }
-        } finally {
-            istream.close();
-        }
-        return bi;
     }
 
Index: /trunk/src/org/openstreetmap/josm/tools/Utils.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/Utils.java	(revision 13355)
+++ /trunk/src/org/openstreetmap/josm/tools/Utils.java	(revision 13356)
@@ -14,4 +14,5 @@
 import java.io.Closeable;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
@@ -26,5 +27,8 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
 import java.security.AccessController;
 import java.security.MessageDigest;
@@ -1736,3 +1740,49 @@
         }
     }
+
+    /**
+     * Convenient method to open an URL stream, using JOSM HTTP client if neeeded.
+     * @param url URL for reading from
+     * @return an input stream for reading from the URL
+     * @throws IOException if any I/O error occurs
+     * @since 13356
+     */
+    public static InputStream openStream(URL url) throws IOException {
+        switch (url.getProtocol()) {
+            case "http":
+            case "https":
+                return HttpClient.create(url).connect().getContent();
+            case "jar":
+                try {
+                    return url.openStream();
+                } catch (FileNotFoundException e) {
+                    // Workaround to https://bugs.openjdk.java.net/browse/JDK-4523159
+                    String urlPath = url.getPath();
+                    if (urlPath.startsWith("file:/") && urlPath.split("!").length > 2) {
+                        try {
+                            // Locate jar file
+                            int index = urlPath.lastIndexOf("!/");
+                            Path jarFile = Paths.get(urlPath.substring("file:/".length(), index));
+                            Path filename = jarFile.getFileName();
+                            FileTime jarTime = Files.readAttributes(jarFile, BasicFileAttributes.class).lastModifiedTime();
+                            // Copy it to temp directory (hopefully free of exclamation mark) if needed (missing or older jar)
+                            Path jarCopy = Paths.get(System.getProperty("java.io.tmpdir")).resolve(filename);
+                            if (!jarCopy.toFile().exists() ||
+                                    Files.readAttributes(jarCopy, BasicFileAttributes.class).lastModifiedTime().compareTo(jarTime) < 0) {
+                                Files.copy(jarFile, jarCopy, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
+                            }
+                            // Open the stream using the copy
+                            return new URL(url.getProtocol() + ':' + jarCopy.toUri().toURL().toExternalForm() + urlPath.substring(index))
+                                    .openStream();
+                        } catch (RuntimeException | IOException ex) {
+                            Logging.warn(ex);
+                        }
+                    }
+                    throw e;
+                }
+            case "file":
+            default:
+                return url.openStream();
+        }
+    }
 }
