Index: /applications/viewer/jmapviewer/build.xml
===================================================================
--- /applications/viewer/jmapviewer/build.xml	(revision 36139)
+++ /applications/viewer/jmapviewer/build.xml	(revision 36140)
@@ -1,4 +1,8 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<project default="all" name="jmapviewer" xmlns:jacoco="antlib:org.jacoco.ant" xmlns:if="ant:if" xmlns:unless="ant:unless">
+<project default="all" name="jmapviewer"
+         xmlns:jacoco="antlib:org.jacoco.ant"
+         xmlns:if="ant:if"
+         xmlns:ivy="antlib:org.apache.ivy.ant"
+>
 
     <property name="java.lang.version" value="8" />
@@ -27,7 +31,4 @@
     </condition>
     <path id="test.classpath">
-        <fileset dir="${tools.dir}/testlib">
-            <include name="**/*.jar"/>
-        </fileset>
         <pathelement location="bin"/>
     </path>
@@ -80,4 +81,8 @@
             </fileset>
         </copy>
+    </target>
+
+    <target name="checkdepsupdate" depends="resolve">
+        <ivy:checkdepsupdate/>
     </target>
 
@@ -132,7 +137,7 @@
     </target>
 
-    <target name="checkstyle">
-        <taskdef resource="com/puppycrawl/tools/checkstyle/ant/checkstyle-ant-task.properties" 
-            classpath="tools/checkstyle/checkstyle-all.jar"/>
+    <target name="checkstyle" depends="resolve">
+        <taskdef resource="com/puppycrawl/tools/checkstyle/ant/checkstyle-ant-task.properties"
+            classpathref="checkstyle.classpath"/>
         <checkstyle config="tools/checkstyle/jmapviewer_checks.xml">
             <!-- Exclude the module-info since checkstyle currently cannot parse it -->
@@ -142,13 +147,8 @@
     </target>
 
-    <target name="spotbugs" depends="pack">
+    <target name="spotbugs" depends="pack,resolve">
         <taskdef name="spotbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask" 
-            classpath="tools/spotbugs/spotbugs-ant.jar"/>
-        <path id="spotbugs-classpath">
-            <fileset dir="tools/spotbugs/">
-                <include name="*.jar"/>
-            </fileset>
-        </path>
-        <property name="spotbugs-classpath" refid="spotbugs-classpath"/>
+            classpathref="spotbugs.classpath"/>
+        <property name="spotbugs-classpath" refid="spotbugs.classpath"/>
         <spotbugs output="xml"
                 outputFile="spotbugs-jmapviewer.xml"
@@ -178,6 +178,14 @@
     </target>
 
-    <target name="test" depends="clean, build">
-        <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml" classpath="${tools.dir}/jacocoant.jar" />
+    <target name="resolve" description="Resolve Ivy dependencies">
+        <ivy:resolve/>
+        <ivy:cachepath pathid="checkstyle.classpath" conf="checkstyle"/>
+        <ivy:cachepath pathid="testlib.classpath" conf="test"/>
+        <ivy:cachepath pathid="jacoco.classpath" conf="jacocoant"/>
+        <ivy:cachepath pathid="spotbugs.classpath" conf="spotbugs"/>
+    </target>
+
+    <target name="test" depends="clean, build, resolve">
+        <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml" classpathref="jacoco.classpath"/>
         <javac srcdir="test" destdir="bintest"
             target="${java.lang.version}" source="${java.lang.version}" debug="on"
@@ -186,22 +194,26 @@
             <compilerarg value="-Xlint:-serial"/>
             <classpath>
-            	<path refid="test.classpath"/>
+                <path refid="testlib.classpath"/>
+                <path refid="test.classpath"/>
             </classpath>
         </javac>
-        <jacoco:coverage enabled="@{coverage}" includes="${jacoco.includes}"
-            inclbootstrapclasses="${jacoco.inclbootstrapclasses}" inclnolocationclasses="${jacoco.inclnolocationclasses}">
-            <junit printsummary="yes" fork="true" forkmode="once">
-                <jvmarg value="-Dfile.encoding=UTF-8"/>
-                <classpath>
-                    <path refid="test.classpath"/>
-                    <pathelement location="bintest"/>
-                </classpath>
-                <formatter type="plain"/>
-                <formatter type="xml"/>
-                <batchtest fork="yes" todir="report">
-                    <fileset dir="bintest" includes="**/*Test.class"/>
-                </batchtest>
-            </junit>
-        </jacoco:coverage>
+        <jacoco:agent enabled="@{coverage}" includes="${jacoco.includes}"
+                      inclbootstrapclasses="${jacoco.inclbootstrapclasses}" inclnolocationclasses="${jacoco.inclnolocationclasses}" property="jacocoagent@{testfamily}@{testITsuffix}" if:true="@{coverage}"/>
+        <junitlauncher printsummary="yes">
+            <classpath>
+                <path refid="testlib.classpath"/>
+                <path refid="test.classpath"/>
+                <pathelement location="bintest"/>
+            </classpath>
+            <testclasses outputdir="report">
+                <fileset dir="bintest" includes="**/*Test.class"/>
+                <fork>
+                    <jvmarg value="-Dfile.encoding=UTF-8"/>
+                </fork>
+                <listener type="legacy-brief" sendSysOut="true" sendSysErr="true"/>
+                <listener type="legacy-plain" />
+                <listener type="legacy-xml" />
+            </testclasses>
+        </junitlauncher>
     </target>
 
Index: /applications/viewer/jmapviewer/ivy.xml
===================================================================
--- /applications/viewer/jmapviewer/ivy.xml	(revision 36140)
+++ /applications/viewer/jmapviewer/ivy.xml	(revision 36140)
@@ -0,0 +1,30 @@
+<ivy-module version="2.0" xmlns:maven="http://ant.apache.org/ivy/maven">
+    <info organisation="org.openstreetmap.josm" module="jmapviewer"/>
+    <configurations>
+        <conf name="spotbugs" visibility="private" description="Everything needed for running SpotBugs"/>
+        <conf name="checkstyle" visibility="private" description="Everything needed for running Checkstyle"/>
+        <conf name="jacocoant" visibility="private" description="Jacoco Ant test library"/>
+        <conf name="test" visibility="private" description="Test libraries"/>
+    </configurations>
+    <dependencies>
+        <!-- jacocoant->default -->
+        <dependency conf="jacocoant->default" org="org.jacoco" name="org.jacoco.ant" rev="0.8.10">
+            <artifact name="org.jacoco.ant" type="jar" maven:classifier="nodeps"/>
+        </dependency>
+        <!-- test->default -->
+        <dependency conf="test->default" org="com.github.spotbugs" name="spotbugs-annotations" rev="4.7.3"/>
+        <dependency conf="test->default" org="org.junit.platform" name="junit-platform-launcher" rev="1.10.0"/>
+        <dependency conf="test->default" org="org.junit.platform" name="junit-platform-suite" rev="1.10.0"/>
+        <dependency conf="test->default" org="org.junit.vintage" name="junit-vintage-engine" rev="5.10.0"/>
+        <dependency conf="test->default" org="org.junit.jupiter" name="junit-jupiter-params" rev="5.10.0"/>
+        <dependency conf="test->default" org="org.junit.jupiter" name="junit-jupiter-api" rev="5.10.0"/>
+        <dependency conf="test->default" org="org.junit.jupiter" name="junit-jupiter-engine" rev="5.10.0"/>
+        <dependency conf="test->default" org="org.junit.jupiter" name="junit-jupiter-migrationsupport" rev="5.10.0"/>
+        <!-- checkstyle->default -->
+        <dependency org="com.puppycrawl.tools" name="checkstyle" rev="9.3" conf="checkstyle->default"/>
+        <!-- spotbugs->default -->
+        <dependency org="com.github.spotbugs" name="spotbugs" rev="4.7.3" conf="spotbugs->default"/>
+        <dependency org="com.github.spotbugs" name="spotbugs-ant" rev="4.7.3" conf="spotbugs->default"/>
+    </dependencies>
+</ivy-module>
+
Index: /applications/viewer/jmapviewer/ivysettings.xml
===================================================================
--- /applications/viewer/jmapviewer/ivysettings.xml	(revision 36140)
+++ /applications/viewer/jmapviewer/ivysettings.xml	(revision 36140)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- License: GPL. For details, see LICENSE file. -->
+<ivysettings>
+  <settings defaultResolver="josm-nexus"/>
+  <resolvers>
+    <ibiblio name="josm-nexus" m2compatible="true" root="https://josm.openstreetmap.de/nexus/content/repositories/public/" />
+  </resolvers>
+</ivysettings>
Index: /applications/viewer/jmapviewer/test/org/openstreetmap/gui/jmapviewer/TileRangeTest.java
===================================================================
--- /applications/viewer/jmapviewer/test/org/openstreetmap/gui/jmapviewer/TileRangeTest.java	(revision 36139)
+++ /applications/viewer/jmapviewer/test/org/openstreetmap/gui/jmapviewer/TileRangeTest.java	(revision 36140)
@@ -2,12 +2,13 @@
 package org.openstreetmap.gui.jmapviewer;
 
-import static org.junit.Assert.assertEquals;
 
-import org.junit.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
 
 /**
  * Unit tests of {@link TileRange} class.
  */
-public class TileRangeTest {
+class TileRangeTest {
 
     /**
@@ -15,5 +16,5 @@
      */
     @Test
-    public void testSize() {
+    void testSize() {
         assertEquals(16, new TileRange(
                 new TileXY(3, 3), 
Index: /applications/viewer/jmapviewer/test/org/openstreetmap/gui/jmapviewer/tilesources/TemplatedTMSTileSourceTest.java
===================================================================
--- /applications/viewer/jmapviewer/test/org/openstreetmap/gui/jmapviewer/tilesources/TemplatedTMSTileSourceTest.java	(revision 36139)
+++ /applications/viewer/jmapviewer/test/org/openstreetmap/gui/jmapviewer/tilesources/TemplatedTMSTileSourceTest.java	(revision 36140)
@@ -2,6 +2,6 @@
 package org.openstreetmap.gui.jmapviewer.tilesources;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.text.MessageFormat;
@@ -11,5 +11,5 @@
 import java.util.stream.Stream;
 
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 /**
@@ -49,5 +49,5 @@
      */
     @Test
-    public void testGetTileUrl() {
+    void testGetTileUrl() {
         checkGetTileUrl(
                 "http://localhost/{z}/{x}/{y}",
@@ -61,5 +61,5 @@
      */
     @Test
-    public void testGetTileUrl_positive_zoom() {
+    void testGetTileUrl_positive_zoom() {
         checkGetTileUrl(
                 "http://localhost/{zoom+5}/{x}/{y}",
@@ -73,5 +73,5 @@
      */
     @Test
-    public void testGetTileUrl_negative_zoom() {
+    void testGetTileUrl_negative_zoom() {
         checkGetTileUrl(
                 "http://localhost/{zoom-5}/{x}/{y}",
@@ -85,5 +85,5 @@
      */
     @Test
-    public void testGetTileUrl_inverse_negative_zoom() {
+    void testGetTileUrl_inverse_negative_zoom() {
         checkGetTileUrl(
                 "http://localhost/{5-zoom}/{x}/{y}",
@@ -97,5 +97,5 @@
      */
     @Test
-    public void testGetTileUrl_both_offsets() {
+    void testGetTileUrl_both_offsets() {
         checkGetTileUrl(
                 "http://localhost/{10-zoom-5}/{x}/{y}",
@@ -109,5 +109,5 @@
      */
     @Test
-    public void testGetTileUrl_apiKey() {
+    void testGetTileUrl_apiKey() {
         System.setProperty("id1.api-key", "wololo");
         TileSourceInfo testImageryTMS = new TileSourceInfo("test imagery", "http://localhost/{zoom}/{x}/{y}?token={apikey}&foo=bar", "id1");
@@ -120,5 +120,5 @@
      */
     @Test
-    public void testGetTileUrl_switch() {
+    void testGetTileUrl_switch() {
         TileSourceInfo testImageryTMS = new TileSourceInfo("test imagery", "http://{switch:a,b,c}.localhost/{10-zoom-5}/{x}/{y}", "id1");
         TemplatedTMSTileSource ts = new TemplatedTMSTileSource(testImageryTMS);
@@ -159,5 +159,5 @@
 
     @Test
-    public void testGetTileUrl_yahoo() {
+    void testGetTileUrl_yahoo() {
         checkGetTileUrl(
                 "http://localhost/{z}/{x}/{!y}",
@@ -169,5 +169,5 @@
 
     @Test
-    public void testGetTileUrl_negative_y() {
+    void testGetTileUrl_negative_y() {
         checkGetTileUrl(
                 "http://localhost/{z}/{x}/{-y}",
@@ -189,5 +189,5 @@
      */
     @Test
-    public void testAllUrls() {
+    void testAllUrls() {
         for (String[] test: TEST_DATA) {
             TileSourceInfo testImageryTMS = new TileSourceInfo("test imagery", test[0], "id1");
