Index: applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/oauth/OAuthUtils.java
===================================================================
--- applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/oauth/OAuthUtils.java	(revision 36065)
+++ applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/oauth/OAuthUtils.java	(revision 36122)
@@ -8,8 +8,8 @@
 import java.net.URL;
 
-import javax.json.Json;
-import javax.json.JsonException;
-import javax.json.JsonObject;
-import javax.json.JsonReader;
+import jakarta.json.Json;
+import jakarta.json.JsonException;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonReader;
 
 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideProperties;
Index: applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonDecoder.java
===================================================================
--- applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonDecoder.java	(revision 36065)
+++ applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonDecoder.java	(revision 36122)
@@ -9,16 +9,15 @@
 import java.util.function.Function;
 
-import javax.json.JsonArray;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonValue;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
 
-import org.apache.log4j.Logger;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.tools.I18n;
+import org.openstreetmap.josm.tools.Logging;
 
 public final class JsonDecoder {
-
-  final static Logger logger = Logger.getLogger(JsonDecoder.class);
+  private static final double[] EMPTY_DOUBLE = new double[0];
 
   private JsonDecoder() {
@@ -65,5 +64,5 @@
   static LatLon decodeLatLon(final JsonArray json) {
     final double[] result = decodeDoublePair(json);
-    if (result != null) {
+    if (result.length == 2) {
       return new LatLon(result[1], result[0]);
     }
@@ -77,5 +76,4 @@
    *         if the parameter was not a {@link JsonArray} of exactly size 2 containing two {@link JsonNumber}s
    */
-  @SuppressWarnings("PMD.ReturnEmptyArrayRatherThanNull")
   static double[] decodeDoublePair(final JsonArray json) {
     if (
@@ -87,5 +85,5 @@
       return new double[]{json.getJsonNumber(0).doubleValue(), json.getJsonNumber(1).doubleValue()};
     }
-    return null;
+    return EMPTY_DOUBLE;
   }
 
@@ -96,5 +94,5 @@
    * @return the point in time as a {@link Long} value representing the UNIX epoch time, or <code>null</code> if the
    *   parameter does not match the required format (this also triggers a warning via
-   *   {@link Logger}, or the parameter is <code>null</code>).
+   *   {@link Logging}, or the parameter is <code>null</code>).
    */
   static Long decodeTimestamp(final String timestamp) {
@@ -104,5 +102,5 @@
       } catch (ParseException e) {
         StackTraceElement calledBy = e.getStackTrace()[Math.min(e.getStackTrace().length - 1, 2)];
-        logger.warn(I18n.tr(String.format(
+        Logging.warn(I18n.tr(String.format(
           "Could not decode time from the timestamp `%s` (called by %s.%s:%d)",
           timestamp, calledBy.getClassName(), calledBy.getMethodName(), calledBy.getLineNumber()
Index: applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonImageDetectionDecoder.java
===================================================================
--- applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonImageDetectionDecoder.java	(revision 36065)
+++ applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonImageDetectionDecoder.java	(revision 36122)
@@ -5,12 +5,12 @@
 import java.awt.geom.Path2D;
 
-import javax.json.JsonArray;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonValue;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonValue;
 
-import org.apache.log4j.Logger;
 import org.openstreetmap.josm.plugins.streetside.model.ImageDetection;
 import org.openstreetmap.josm.plugins.streetside.utils.StreetsideURL.APIv3;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -19,6 +19,4 @@
  */
 public final class JsonImageDetectionDecoder {
-
-  final static Logger logger = Logger.getLogger(JsonImageDetectionDecoder.class);
 
   private JsonImageDetectionDecoder() {
@@ -50,5 +48,5 @@
     if (json instanceof JsonObject) {
       if (!"Polygon".equals(((JsonObject) json).getString("type", null))) {
-        logger.warn(
+        Logging.warn(
           String.format("Image detections using shapes with type=%s are currently not supported!",
           ((JsonObject) json).getString("type", "‹no type set›"))
@@ -93,7 +91,7 @@
     json.forEach(val -> {
       double[] coord = JsonDecoder.decodeDoublePair(val instanceof JsonArray ? (JsonArray) val : null);
-      if (shape.getCurrentPoint() == null && coord != null) {
+      if (shape.getCurrentPoint() == null && coord.length == 2) {
         shape.moveTo(coord[0], coord[1]);
-      } else if (coord != null) {
+      } else if (coord != null && coord.length == 2) {
         shape.lineTo(coord[0], coord[1]);
       }
Index: applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonSequencesDecoder.java
===================================================================
--- applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonSequencesDecoder.java	(revision 36065)
+++ applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonSequencesDecoder.java	(revision 36122)
@@ -5,9 +5,9 @@
 import java.util.function.Function;
 
-import javax.json.JsonArray;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonString;
-import javax.json.JsonValue;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
 
 import org.openstreetmap.josm.data.coor.LatLon;
Index: applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonStreetsideDecoder.java
===================================================================
--- applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonStreetsideDecoder.java	(revision 36065)
+++ applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonStreetsideDecoder.java	(revision 36122)
@@ -2,23 +2,16 @@
 package org.openstreetmap.josm.plugins.streetside.utils.api;
 
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
 import java.util.Collection;
 import java.util.HashSet;
-import java.util.Locale;
 import java.util.function.Function;
 
-import javax.json.JsonArray;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonValue;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.tools.Logging;
 
-import org.apache.log4j.Logger;
-import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.tools.I18n;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
 
 public final class JsonStreetsideDecoder {
-
-  final static Logger logger = Logger.getLogger(JsonStreetsideDecoder.class);
 
   private JsonStreetsideDecoder() {
@@ -38,20 +31,5 @@
    */
   public static <T> Collection<T> decodeFeatureCollection(final JsonObject json, Function<JsonObject, T> featureDecoder) {
-    final Collection<T> result = new HashSet<>();
-    if (
-      json != null && "FeatureCollection".equals(json.getString("type", null)) && json.containsKey("features")
-    ) {
-      final JsonValue features = json.get("features");
-      for (int i = 0; features instanceof JsonArray && i < ((JsonArray) features).size(); i++) {
-        final JsonValue val = ((JsonArray) features).get(i);
-        if (val instanceof JsonObject) {
-          final T feature = featureDecoder.apply((JsonObject) val);
-          if (feature != null) {
-            result.add(feature);
-          }
-        }
-      }
-    }
-    return result;
+    return JsonDecoder.decodeFeatureCollection(json, featureDecoder);
   }
 
@@ -64,28 +42,5 @@
    */
   static LatLon decodeLatLon(final JsonArray json) {
-    final double[] result = decodeDoublePair(json);
-    if (result != null) {
-      return new LatLon(result[1], result[0]);
-    }
-    return null;
-  }
-
-  /**
-   * Decodes a pair of double values, which are stored in a {@link JsonArray} of exactly size 2.
-   * @param json the {@link JsonArray} containing the two values
-   * @return a double array which contains the two values in the same order, or <code>null</code>
-   *         if the parameter was not a {@link JsonArray} of exactly size 2 containing two {@link JsonNumber}s
-   */
-  @SuppressWarnings("PMD.ReturnEmptyArrayRatherThanNull")
-  static double[] decodeDoublePair(final JsonArray json) {
-    if (
-      json != null &&
-      json.size() == 2 &&
-      json.get(0) instanceof JsonNumber &&
-      json.get(1) instanceof JsonNumber
-    ) {
-      return new double[]{json.getJsonNumber(0).doubleValue(), json.getJsonNumber(1).doubleValue()};
-    }
-    return null;
+    return JsonDecoder.decodeLatLon(json);
   }
 
@@ -96,19 +51,8 @@
    * @return the point in time as a {@link Long} value representing the UNIX epoch time, or <code>null</code> if the
    *   parameter does not match the required format (this also triggers a warning via
-   *   {@link Logger}, or the parameter is <code>null</code>).
+   *   {@link Logging}, or the parameter is <code>null</code>).
    */
   static Long decodeTimestamp(final String timestamp) {
-    if (timestamp != null) {
-      try {
-        return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.UK).parse(timestamp).getTime();
-      } catch (ParseException e) {
-        StackTraceElement calledBy = e.getStackTrace()[Math.min(e.getStackTrace().length - 1, 2)];
-        logger.warn(I18n.tr(String.format(
-          "Could not decode time from the timestamp `%s` (called by %s.%s:%d)",
-          timestamp, calledBy.getClassName(), calledBy.getMethodName(), calledBy.getLineNumber()
-        ), e));
-      }
-    }
-    return null;
+    return JsonDecoder.decodeTimestamp(timestamp);
   }
 }
Index: applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonStreetsideSequencesDecoder.java
===================================================================
--- applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonStreetsideSequencesDecoder.java	(revision 36065)
+++ applications/editors/josm/plugins/MicrosoftStreetside/src/org/openstreetmap/josm/plugins/streetside/utils/api/JsonStreetsideSequencesDecoder.java	(revision 36122)
@@ -5,9 +5,9 @@
 import java.util.function.Function;
 
-import javax.json.JsonArray;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonString;
-import javax.json.JsonValue;
+import jakarta.json.JsonArray;
+import jakarta.json.JsonNumber;
+import jakarta.json.JsonObject;
+import jakarta.json.JsonString;
+import jakarta.json.JsonValue;
 
 import org.openstreetmap.josm.data.coor.LatLon;
@@ -113,5 +113,6 @@
 
     if (json.getString("id", null) != null && json.getString("la", null) != null && json.getString("lo", null) != null) {
-        result = new StreetsideSequence(json.getString("id", null), json.getJsonNumber("la").doubleValue(), json.getJsonNumber("lo").doubleValue(), json.getJsonNumber("cd").longValue());
+        result = new StreetsideSequence(json.getString("id", null),
+                json.getJsonNumber("la").doubleValue(), json.getJsonNumber("lo").doubleValue(), json.getJsonNumber("cd").longValue());
     }
 
