diff --git a/geowebcache/azureblob/src/main/java/org/geowebcache/azure/AzureClient.java b/geowebcache/azureblob/src/main/java/org/geowebcache/azure/AzureClient.java index 4a5ac008d2..2aa9726e53 100644 --- a/geowebcache/azureblob/src/main/java/org/geowebcache/azure/AzureClient.java +++ b/geowebcache/azureblob/src/main/java/org/geowebcache/azure/AzureClient.java @@ -40,7 +40,6 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.Proxy; -import java.net.URL; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -48,6 +47,7 @@ import java.util.Properties; import javax.annotation.Nullable; import org.geowebcache.storage.StorageException; +import org.geowebcache.util.URLs; import org.springframework.http.HttpStatus; class AzureClient implements Closeable { @@ -86,7 +86,7 @@ public AzureClient(AzureBlobStoreData configuration) throws StorageException { PipelineOptions options = new PipelineOptions().withClient(client); ServiceURL serviceURL = new ServiceURL( - new URL(getServiceURL(configuration)), + URLs.of(getServiceURL(configuration)), StorageURL.createPipeline(creds, options)); String containerName = configuration.getContainer(); diff --git a/geowebcache/core/src/main/java/org/geowebcache/config/XMLConfiguration.java b/geowebcache/core/src/main/java/org/geowebcache/config/XMLConfiguration.java index e9c65be9cb..30513e3af0 100644 --- a/geowebcache/core/src/main/java/org/geowebcache/config/XMLConfiguration.java +++ b/geowebcache/core/src/main/java/org/geowebcache/config/XMLConfiguration.java @@ -88,6 +88,7 @@ import org.geowebcache.storage.UnsuitableStorageException; import org.geowebcache.util.ApplicationContextProvider; import org.geowebcache.util.ExceptionUtils; +import org.geowebcache.util.URLs; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -266,10 +267,10 @@ public void setDefaultValues(TileLayer layer) { URL proxyUrl = null; try { if (getGwcConfig().getProxyUrl() != null) { - proxyUrl = new URL(getGwcConfig().getProxyUrl()); + proxyUrl = URLs.of(getGwcConfig().getProxyUrl()); log.fine("Using proxy " + proxyUrl.getHost() + ":" + proxyUrl.getPort()); } else if (wl.getProxyUrl() != null) { - proxyUrl = new URL(wl.getProxyUrl()); + proxyUrl = URLs.of(wl.getProxyUrl()); log.fine("Using proxy " + proxyUrl.getHost() + ":" + proxyUrl.getPort()); } } catch (MalformedURLException e) { diff --git a/geowebcache/core/src/main/java/org/geowebcache/config/XMLOldGrid.java b/geowebcache/core/src/main/java/org/geowebcache/config/XMLOldGrid.java index b2e465b7d1..f4b2e11378 100644 --- a/geowebcache/core/src/main/java/org/geowebcache/config/XMLOldGrid.java +++ b/geowebcache/core/src/main/java/org/geowebcache/config/XMLOldGrid.java @@ -22,6 +22,7 @@ import org.geowebcache.grid.GridSubset; import org.geowebcache.grid.GridSubsetFactory; import org.geowebcache.grid.SRS; +import org.geowebcache.util.SuppressFBWarnings; /** * This class exists mainly to parse the old XML objects using XStream @@ -29,6 +30,11 @@ *
The problem is that it cannot use the GridSetBroker, so we end up with one GridSet per layer * anyway. */ +@SuppressFBWarnings({ + "NP_UNWRITTEN_FIELD", + "NP_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", + "UWF_NULL_FIELD" +}) // field assignment done by XStream public class XMLOldGrid implements Serializable { private static final long serialVersionUID = 1413422643636728997L; diff --git a/geowebcache/core/src/main/java/org/geowebcache/filter/request/WMSRasterFilter.java b/geowebcache/core/src/main/java/org/geowebcache/filter/request/WMSRasterFilter.java index 4e866e324a..c72cdecef9 100644 --- a/geowebcache/core/src/main/java/org/geowebcache/filter/request/WMSRasterFilter.java +++ b/geowebcache/core/src/main/java/org/geowebcache/filter/request/WMSRasterFilter.java @@ -34,6 +34,7 @@ import org.geowebcache.layer.wms.WMSLayer; import org.geowebcache.mime.ImageMime; import org.geowebcache.util.ServletUtils; +import org.geowebcache.util.URLs; public class WMSRasterFilter extends RasterFilter { @@ -110,7 +111,7 @@ protected BufferedImage loadMatrix(TileLayer tlayer, String gridSetId, int z) + ") , " + urlStr); - URL wmsUrl = new URL(urlStr); + URL wmsUrl = URLs.of(urlStr); if (backendTimeout == null) { backendTimeout = 120; diff --git a/geowebcache/core/src/main/java/org/geowebcache/layer/TileLayerDispatcher.java b/geowebcache/core/src/main/java/org/geowebcache/layer/TileLayerDispatcher.java index 93b7729900..09a545754a 100644 --- a/geowebcache/core/src/main/java/org/geowebcache/layer/TileLayerDispatcher.java +++ b/geowebcache/core/src/main/java/org/geowebcache/layer/TileLayerDispatcher.java @@ -113,7 +113,7 @@ public TileLayer getTileLayer(final String layerName) throws GeoWebCacheExceptio } throw new GeoWebCacheException( "Thread " - + Thread.currentThread().getId() + + Thread.currentThread().getName() + " Unknown layer " + layerName + ". Check the logfiles," diff --git a/geowebcache/core/src/main/java/org/geowebcache/layer/wms/WMSHttpHelper.java b/geowebcache/core/src/main/java/org/geowebcache/layer/wms/WMSHttpHelper.java index 58fa3b66c4..782c9bad21 100644 --- a/geowebcache/core/src/main/java/org/geowebcache/layer/wms/WMSHttpHelper.java +++ b/geowebcache/core/src/main/java/org/geowebcache/layer/wms/WMSHttpHelper.java @@ -46,6 +46,7 @@ import org.geowebcache.util.GWCVars; import org.geowebcache.util.HttpClientBuilder; import org.geowebcache.util.ServletUtils; +import org.geowebcache.util.URLs; import org.springframework.util.Assert; /** This class is a wrapper for HTTP interaction with WMS backend */ @@ -115,7 +116,7 @@ protected void makeRequest( String requestUrl = layer.nextWmsURL(); try { - wmsBackendUrl = new URL(requestUrl); + wmsBackendUrl = URLs.of(requestUrl); } catch (MalformedURLException maue) { throw new GeoWebCacheException( "Malformed URL: " + requestUrl + " " + maue.getMessage()); diff --git a/geowebcache/core/src/main/java/org/geowebcache/layer/wms/WMSLayer.java b/geowebcache/core/src/main/java/org/geowebcache/layer/wms/WMSLayer.java index c5acd475e4..c5532db7ce 100644 --- a/geowebcache/core/src/main/java/org/geowebcache/layer/wms/WMSLayer.java +++ b/geowebcache/core/src/main/java/org/geowebcache/layer/wms/WMSLayer.java @@ -54,6 +54,7 @@ import org.geowebcache.mime.MimeType; import org.geowebcache.mime.XMLMime; import org.geowebcache.util.GWCVars; +import org.geowebcache.util.URLs; /** A tile layer backed by a WMS server */ public class WMSLayer extends AbstractTileLayer implements ProxyLayer { @@ -803,9 +804,9 @@ public void proxyRequest(ConveyorTile tile) throws GeoWebCacheException { try { URL url; if (serverStr.contains("?")) { - url = new URL(serverStr + "&" + queryStr); + url = URLs.of(serverStr + "&" + queryStr); } else { - url = new URL(serverStr + queryStr); + url = URLs.of(serverStr + queryStr); } WMSSourceHelper helper = getSourceHelper(); diff --git a/geowebcache/core/src/main/java/org/geowebcache/locks/NIOLockProvider.java b/geowebcache/core/src/main/java/org/geowebcache/locks/NIOLockProvider.java index 500945e1b3..cdedf4aa7f 100644 --- a/geowebcache/core/src/main/java/org/geowebcache/locks/NIOLockProvider.java +++ b/geowebcache/core/src/main/java/org/geowebcache/locks/NIOLockProvider.java @@ -115,7 +115,7 @@ public LockProvider.Lock getLock(final String lockKey) throws GeoWebCacheExcepti "Lock " + lockKey + " acquired by thread " - + Thread.currentThread().getId() + + Thread.currentThread().getName() + " on file " + file); } @@ -151,7 +151,7 @@ public void release() throws GeoWebCacheException { + " for releasing lock is unkonwn, it means " + "this lock was never acquired, or was released twice. " + "Current thread is: " - + Thread.currentThread().getId() + + Thread.currentThread().getName() + ". " + "Are you running two GWC instances in the same JVM using NIO locks? " + "This case is not supported and will generate exactly this error message"); @@ -170,7 +170,7 @@ public void release() throws GeoWebCacheException { + " on file " + lockFile + " released by thread " - + Thread.currentThread().getId()); + + Thread.currentThread().getName()); } } catch (IOException e) { throw new GeoWebCacheException( diff --git a/geowebcache/core/src/main/java/org/geowebcache/proxy/ProxyDispatcher.java b/geowebcache/core/src/main/java/org/geowebcache/proxy/ProxyDispatcher.java index 1db4fe9527..000d385e1a 100644 --- a/geowebcache/core/src/main/java/org/geowebcache/proxy/ProxyDispatcher.java +++ b/geowebcache/core/src/main/java/org/geowebcache/proxy/ProxyDispatcher.java @@ -22,6 +22,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.geotools.util.logging.Logging; +import org.geowebcache.util.URLs; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.AbstractController; @@ -62,7 +63,7 @@ protected ModelAndView handleRequestInternal( } String decodedUrl = URLDecoder.decode(urlStr, charEnc); - URL url = new URL(decodedUrl); + URL url = URLs.of(decodedUrl); HttpURLConnection wmsBackendCon = (HttpURLConnection) url.openConnection(); if (wmsBackendCon.getContentEncoding() != null) { diff --git a/geowebcache/core/src/main/java/org/geowebcache/storage/BlobStoreAggregator.java b/geowebcache/core/src/main/java/org/geowebcache/storage/BlobStoreAggregator.java index 1ccbe669cf..bc6d841ae2 100644 --- a/geowebcache/core/src/main/java/org/geowebcache/storage/BlobStoreAggregator.java +++ b/geowebcache/core/src/main/java/org/geowebcache/storage/BlobStoreAggregator.java @@ -103,7 +103,7 @@ public BlobStoreInfo getBlobStore(final String blobStoreName) throws GeoWebCache () -> new GeoWebCacheException( "Thread " - + Thread.currentThread().getId() + + Thread.currentThread().getName() + " Unknown blob store " + blobStoreName + ". Check the logfiles," diff --git a/geowebcache/core/src/main/java/org/geowebcache/util/URLs.java b/geowebcache/core/src/main/java/org/geowebcache/util/URLs.java new file mode 100644 index 0000000000..ba63849488 --- /dev/null +++ b/geowebcache/core/src/main/java/org/geowebcache/util/URLs.java @@ -0,0 +1,54 @@ +/** + * This program is free software: you can redistribute it and/or modify it under the terms of the + * GNU Lesser General Public License as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + *
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + *
You should have received a copy of the GNU Lesser General Public License along with this
+ * program. If not, see
Prefer this method to {@code new URL(String)}, which is deprecated + * in Java 21. + * + *
Note a {@link URISyntaxException} will be rethrown as {@link MalformedURLException} to
+ * preserve the behavior of code that used to call {@code new URL(String)} and expected either a
+ * {@code MalformedURLException} or its super type {@code java.io.IOException}.
+ *
+ * @param url a URL string to build a {@link URL} from
+ * @return the URL built from the argument
+ * @throws MalformedURLException if {code}url{code} is not a valid {@link URI} nor a valid
+ * {@link URL} as per {@link URI#toURL()}
+ */
+ public static URL of(String url) throws MalformedURLException {
+ try {
+ return new URI(url).toURL();
+ } catch (URISyntaxException orig) {
+ MalformedURLException e = new MalformedURLException(orig.getMessage());
+ e.initCause(orig);
+ throw e;
+ }
+ }
+}
diff --git a/geowebcache/core/src/test/java/org/geowebcache/blobstore/file/FileBlobStoreComformanceTest.java b/geowebcache/core/src/test/java/org/geowebcache/blobstore/file/FileBlobStoreComformanceTest.java
index b4e9397e12..0050490bf5 100644
--- a/geowebcache/core/src/test/java/org/geowebcache/blobstore/file/FileBlobStoreComformanceTest.java
+++ b/geowebcache/core/src/test/java/org/geowebcache/blobstore/file/FileBlobStoreComformanceTest.java
@@ -50,6 +50,7 @@ public void createTestUnit() throws Exception {
private void putLayerMetadataConcurrently(
final int srcStoreKey, final FileBlobStore srcStore, int numberOfThreads)
throws InterruptedException {
+ @SuppressWarnings("PMD.CloseResource") // implements AutoCloseable in Java 21
ExecutorService service = Executors.newFixedThreadPool(numberOfThreads);
CountDownLatch latch = new CountDownLatch(numberOfThreads);
for (int i = 0; i < numberOfThreads; i++) {
@@ -75,6 +76,7 @@ private void putLayerMetadataConcurrently(
private void executeStoresConcurrently(int numberOfStores, int numberOfThreads)
throws InterruptedException {
+ @SuppressWarnings("PMD.CloseResource") // implements AutoCloseable in Java 21
ExecutorService service = Executors.newFixedThreadPool(numberOfStores);
CountDownLatch latch = new CountDownLatch(numberOfStores);
for (int i = 0; i < numberOfStores; i++) {
@@ -106,6 +108,7 @@ public void testMetadataWithPointInKey() throws Exception {
public void testConcurrentMetadataWithPointInKey() throws InterruptedException {
assertThat(store.getLayerMetadata("testLayer", "test.Key"), nullValue());
int numberOfThreads = 2;
+ @SuppressWarnings("PMD.CloseResource") // implements AutoCloseable in Java 21
ExecutorService service = Executors.newFixedThreadPool(numberOfThreads);
CountDownLatch latch = new CountDownLatch(numberOfThreads);
for (int i = 0; i < numberOfThreads; i++) {
diff --git a/geowebcache/core/src/test/java/org/geowebcache/config/ConfigurationTest.java b/geowebcache/core/src/test/java/org/geowebcache/config/ConfigurationTest.java
index 9e967a28f3..2b6ef36c9e 100644
--- a/geowebcache/core/src/test/java/org/geowebcache/config/ConfigurationTest.java
+++ b/geowebcache/core/src/test/java/org/geowebcache/config/ConfigurationTest.java
@@ -345,6 +345,7 @@ public void testConcurrentAdds() throws Exception {
defaultCount + 10,
getInfoNames(config).size());
// get a thread pool
+ @SuppressWarnings("PMD.CloseResource") // implements AutoCloseable in Java 21
ExecutorService pool =
Executors.newFixedThreadPool(
16, (Runnable r) -> new Thread(r, "Info Concurrency Test for ADD"));
@@ -389,6 +390,7 @@ public void testConcurrentDeletes() throws Exception {
defaultCount + 100,
getInfoNames(config).size());
// get a thread pool
+ @SuppressWarnings("PMD.CloseResource") // implements AutoCloseable in Java 21
ExecutorService pool =
Executors.newFixedThreadPool(
16, (Runnable r) -> new Thread(r, "Info Concurrency Test for DELETE"));
@@ -431,6 +433,7 @@ public void testConcurrentModifies() throws Exception {
defaultCount + 100,
getInfoNames(config).size());
// get a thread pool
+ @SuppressWarnings("PMD.CloseResource") // implements AutoCloseable in Java 21
ExecutorService pool =
Executors.newFixedThreadPool(
16, (Runnable r) -> new Thread(r, "Info Concurrency Test for MODIFY"));
diff --git a/geowebcache/core/src/test/java/org/geowebcache/config/DefaultingConfigurationTest.java b/geowebcache/core/src/test/java/org/geowebcache/config/DefaultingConfigurationTest.java
index 6b5a2e1457..684a2b1704 100644
--- a/geowebcache/core/src/test/java/org/geowebcache/config/DefaultingConfigurationTest.java
+++ b/geowebcache/core/src/test/java/org/geowebcache/config/DefaultingConfigurationTest.java
@@ -27,6 +27,7 @@
import org.geowebcache.layer.TileLayer;
import org.geowebcache.layer.wms.WMSHttpHelper;
import org.geowebcache.layer.wms.WMSLayer;
+import org.geowebcache.util.URLs;
import org.junit.Test;
public class DefaultingConfigurationTest {
@@ -111,9 +112,9 @@ public void setDefaultValues(TileLayer layer) {
URL proxyUrl = null;
try {
if (getGwcConfig().getProxyUrl() != null) {
- proxyUrl = new URL(getGwcConfig().getProxyUrl());
+ proxyUrl = URLs.of(getGwcConfig().getProxyUrl());
} else if (wl.getProxyUrl() != null) {
- proxyUrl = new URL(wl.getProxyUrl());
+ proxyUrl = URLs.of(wl.getProxyUrl());
}
} catch (MalformedURLException e) {
}
diff --git a/geowebcache/core/src/test/java/org/geowebcache/layer/wms/WMSLayerTest.java b/geowebcache/core/src/test/java/org/geowebcache/layer/wms/WMSLayerTest.java
index dbb4f32a2d..353bbdaea9 100644
--- a/geowebcache/core/src/test/java/org/geowebcache/layer/wms/WMSLayerTest.java
+++ b/geowebcache/core/src/test/java/org/geowebcache/layer/wms/WMSLayerTest.java
@@ -601,6 +601,7 @@ private List