Using Java9+ NIO API for improved performance: Modern JREs offload to OS, and do other tricks.
diff --git a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java
index 0e36dee..1247447 100644
--- a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java
+++ b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2024 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -743,7 +743,8 @@
             if (i.markSupported()) {
                 inputStream = i;
             } else {
-                inputStream = new BufferedInputStream(i, ReaderWriter.BUFFER_SIZE);
+                inputStream = ReaderWriter.AUTOSIZE_BUFFER ? new BufferedInputStream(i)
+                        : new BufferedInputStream(i, ReaderWriter.BUFFER_SIZE);
             }
         }
 
diff --git a/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5Connector.java b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5Connector.java
index 8d93b91..6169a16 100644
--- a/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5Connector.java
+++ b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5Connector.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, 2024 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -754,7 +754,8 @@
             if (i.markSupported()) {
                 inputStream = i;
             } else {
-                inputStream = new BufferedInputStream(i, ReaderWriter.BUFFER_SIZE);
+                inputStream = ReaderWriter.AUTOSIZE_BUFFER ? new BufferedInputStream(i)
+                        : new BufferedInputStream(i, ReaderWriter.BUFFER_SIZE);
             }
         }
 
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/AbstractMessageReaderWriterProvider.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/AbstractMessageReaderWriterProvider.java
index f7e2673..466eaaa 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/AbstractMessageReaderWriterProvider.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/AbstractMessageReaderWriterProvider.java
@@ -46,7 +46,7 @@
      *
      * @deprecated use {@code StandardCharsets.UTF_8} instead.
      */
-    @Deprecated
+    @Deprecated(forRemoval = true)
     public static final Charset UTF8 = StandardCharsets.UTF_8;
 
     /**
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/CommittingOutputStream.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/CommittingOutputStream.java
index 39f74fb..29be49f 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/CommittingOutputStream.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/CommittingOutputStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -62,7 +62,7 @@
      * Null stream provider.
      */
     private static final OutboundMessageContext.StreamProvider NULL_STREAM_PROVIDER =
-            contentLength -> new NullOutputStream();
+            contentLength -> OutputStream.nullOutputStream();
     /**
      * Default size of the buffer which will be used if no user defined size is specified.
      */
@@ -170,7 +170,7 @@
             Preconditions.checkState(streamProvider != null, STREAM_PROVIDER_NULL);
             adaptedOutput = streamProvider.getOutputStream(currentSize);
             if (adaptedOutput == null) {
-                adaptedOutput = new NullOutputStream();
+                adaptedOutput = OutputStream.nullOutputStream();
             }
 
             directWrite = true;
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/InputStreamProvider.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/InputStreamProvider.java
index c07dcbf..6bf66cb 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/InputStreamProvider.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/InputStreamProvider.java
@@ -78,10 +78,8 @@
             MediaType mediaType,
             MultivaluedMap<String, Object> httpHeaders,
             OutputStream entityStream) throws IOException {
-        try {
+        try (t) {
             ReaderWriter.writeTo(t, entityStream);
-        } finally {
-            t.close();
         }
     }
 }
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/NullOutputStream.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/NullOutputStream.java
deleted file mode 100644
index 26d3f14..0000000
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/NullOutputStream.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v. 2.0, which is available at
- * http://www.eclipse.org/legal/epl-2.0.
- *
- * This Source Code may also be made available under the following Secondary
- * Licenses when the conditions for such availability set forth in the
- * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
- * version 2 with the GNU Classpath Exception, which is available at
- * https://www.gnu.org/software/classpath/license.html.
- *
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
- */
-
-package org.glassfish.jersey.message.internal;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.glassfish.jersey.internal.LocalizationMessages;
-
-/**
- * A {@code "dev/null"} output stream - an output stream implementation that discards all the
- * data written to it. This implementation is not thread-safe.
- *
- * Note that once a null output stream instance is {@link #close() closed}, any subsequent attempts
- * to write the data to the closed stream result in an {@link java.io.IOException} being thrown.
- *
- * @author Miroslav Fuksa
- * @author Marek Potociar
- */
-public class NullOutputStream extends OutputStream {
-
-    private boolean isClosed;
-
-    @Override
-    public void write(int b) throws IOException {
-        checkClosed();
-    }
-
-    @Override
-    public void write(byte[] b, int off, int len) throws IOException {
-        checkClosed();
-        if (b == null) {
-            throw new NullPointerException();
-        } else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) {
-            throw new IndexOutOfBoundsException();
-        }
-    }
-
-    @Override
-    public void flush() throws IOException {
-        checkClosed();
-    }
-
-    private void checkClosed() throws IOException {
-        if (isClosed) {
-            throw new IOException(LocalizationMessages.OUTPUT_STREAM_CLOSED());
-        }
-    }
-
-    @Override
-    public void close() throws IOException {
-        isClosed = true;
-    }
-}
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/ReaderWriter.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/ReaderWriter.java
index 018c9f0..ae8e7d8 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/ReaderWriter.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/ReaderWriter.java
@@ -43,7 +43,7 @@
  * A utility class for reading and writing using byte and character streams.
  * <p>
  * If a byte or character array is utilized then the size of the array
- * is by default the value of {@value org.glassfish.jersey.message.MessageProperties#IO_DEFAULT_BUFFER_SIZE}.
+ * is by default decided by the JRE.
  * This value can be set using the system property
  * {@value org.glassfish.jersey.message.MessageProperties#IO_BUFFER_SIZE}.
  *
@@ -57,14 +57,19 @@
      *
      * @deprecated use {@code StandardCharsets.UTF_8} instead
      */
-    @Deprecated
+    @Deprecated(forRemoval = true)
     public static final Charset UTF8 = StandardCharsets.UTF_8;
     /**
      * The buffer size for arrays of byte and character.
      */
     public static final int BUFFER_SIZE = getBufferSize();
 
-    private static int getBufferSize() {
+    /**
+     * Whether {@linkplain BUFFER_SIZE} is to be ignored in favor of JRE's own decision.
+     */
+    public static final boolean AUTOSIZE_BUFFER = getAutosizeBuffer();
+
+    private static int getIOBufferSize() {
         // TODO should we unify this buffer size and CommittingOutputStream buffer size (controlled by CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER)?
         final String value = AccessController.doPrivileged(PropertiesHelper.getSystemProperty(MessageProperties.IO_BUFFER_SIZE));
         if (value != null) {
@@ -78,11 +83,20 @@
                 LOGGER.log(Level.CONFIG,
                         "Value of " + MessageProperties.IO_BUFFER_SIZE
                                 + " property is not a valid positive integer [" + value + "]."
-                                + " Reverting to default [" + MessageProperties.IO_DEFAULT_BUFFER_SIZE + "].",
+                                + " Reverting to default [at JRE's discretion].",
                         e);
             }
         }
-        return MessageProperties.IO_DEFAULT_BUFFER_SIZE;
+        return -1;
+    }
+
+    private static int getBufferSize() {
+        final int ioBufferSize = getIOBufferSize();
+        return ioBufferSize == -1 ? MessageProperties.IO_DEFAULT_BUFFER_SIZE : ioBufferSize;
+    }
+
+    private static boolean getAutosizeBuffer() {
+        return getIOBufferSize() == -1;
     }
 
     /**
@@ -93,6 +107,11 @@
      * @throws IOException if there is an error reading or writing bytes.
      */
     public static void writeTo(InputStream in, OutputStream out) throws IOException {
+        if (AUTOSIZE_BUFFER) {
+            in.transferTo(out);
+            return;
+        }
+
         int read;
         final byte[] data = new byte[BUFFER_SIZE];
         while ((read = in.read(data)) != -1) {
@@ -108,6 +127,11 @@
      * @throws IOException if there is an error reading or writing characters.
      */
     public static void writeTo(Reader in, Writer out) throws IOException {
+        if (AUTOSIZE_BUFFER) {
+            in.transferTo(out);
+            return;
+        }
+
         int read;
         final char[] data = new char[BUFFER_SIZE];
         while ((read = in.read(data)) != -1) {
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java b/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java
index 7d75df1..730d1ce 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ApplicationHandler.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2023 Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2018 Payara Foundation and/or its affiliates.
  *
  * This program and the accompanying materials are made available under the
@@ -66,7 +66,6 @@
 import org.glassfish.jersey.message.MessageBodyWorkers;
 import org.glassfish.jersey.message.internal.MessageBodyFactory;
 import org.glassfish.jersey.message.internal.MessagingBinders;
-import org.glassfish.jersey.message.internal.NullOutputStream;
 import org.glassfish.jersey.model.internal.ComponentBag;
 import org.glassfish.jersey.model.internal.ManagedObjectsFinalizer;
 import org.glassfish.jersey.model.internal.RankedComparator;
@@ -586,7 +585,7 @@
      * @return response future.
      */
     public Future<ContainerResponse> apply(final ContainerRequest requestContext) {
-        return apply(requestContext, new NullOutputStream());
+        return apply(requestContext, OutputStream.nullOutputStream());
     }
 
     /**
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/JarZipSchemeResourceFinderFactory.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/JarZipSchemeResourceFinderFactory.java
index f08cfb1..501372a 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/JarZipSchemeResourceFinderFactory.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/JarZipSchemeResourceFinderFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2024 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -22,7 +22,7 @@
 import java.net.URI;
 import java.net.URL;
 import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
@@ -155,7 +155,7 @@
             return new URL(jarUrlString).openStream();
         } catch (final MalformedURLException e) {
             return Files.newInputStream(
-                    Paths.get(UriComponent.decode(jarUrlString, UriComponent.Type.PATH)));
+                    Path.of(UriComponent.decode(jarUrlString, UriComponent.Type.PATH)));
         }
     }
 }
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/JarUtils.java b/core-server/src/test/java/org/glassfish/jersey/server/JarUtils.java
index 50a5402..003a735 100644
--- a/core-server/src/test/java/org/glassfish/jersey/server/JarUtils.java
+++ b/core-server/src/test/java/org/glassfish/jersey/server/JarUtils.java
@@ -90,11 +90,7 @@
 
             final InputStream f = new BufferedInputStream(
                     Files.newInputStream(new File(base, entry.getKey()).toPath()));
-            final byte[] buf = new byte[1024];
-            int read = 1024;
-            while ((read = f.read(buf, 0, read)) != -1) {
-                jos.write(buf, 0, read);
-            }
+            f.transferTo(jos);
             jos.closeEntry();
         }
 
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/internal/scanning/JarFileScannerTest.java b/core-server/src/test/java/org/glassfish/jersey/server/internal/scanning/JarFileScannerTest.java
index bdceaa1..a283a59 100644
--- a/core-server/src/test/java/org/glassfish/jersey/server/internal/scanning/JarFileScannerTest.java
+++ b/core-server/src/test/java/org/glassfish/jersey/server/internal/scanning/JarFileScannerTest.java
@@ -19,7 +19,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.Enumeration;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
@@ -114,7 +114,7 @@
     private int countJarEntriesUsingScanner(final String parent, final boolean recursive) throws IOException {
         int scannedEntryCount = 0;
 
-        try (final InputStream jaxRsApi = Files.newInputStream(Paths.get(this.jaxRsApiPath))) {
+        try (final InputStream jaxRsApi = Files.newInputStream(Path.of(this.jaxRsApiPath))) {
             final JarFileScanner jarFileScanner = new JarFileScanner(jaxRsApi, parent, recursive);
             while (jarFileScanner.hasNext()) {
                 // Fetch next entry.
@@ -136,7 +136,7 @@
     @ParameterizedTest
     @ValueSource(booleans = {true, false})
     public void testClassEnumerationWithNonexistentPackage(final boolean recursive) throws IOException {
-        try (final InputStream jaxRsApi = Files.newInputStream(Paths.get(this.jaxRsApiPath))) {
+        try (final InputStream jaxRsApi = Files.newInputStream(Path.of(this.jaxRsApiPath))) {
             final JarFileScanner jarFileScanner = new JarFileScanner(jaxRsApi, "jakarta/ws/r", recursive);
             assertFalse(jarFileScanner.hasNext(), "Unexpectedly found package 'jakarta.ws.r' in jakarta.ws.rs-api");
         }
@@ -145,7 +145,7 @@
     @ParameterizedTest
     @ValueSource(booleans = {true, false})
     public void testClassEnumerationWithClassPrefix(final boolean recursive) throws IOException {
-        try (final InputStream jaxRsApi = Files.newInputStream(Paths.get(this.jaxRsApiPath))) {
+        try (final InputStream jaxRsApi = Files.newInputStream(Path.of(this.jaxRsApiPath))) {
             final JarFileScanner jarFileScanner = new JarFileScanner(jaxRsApi, "jakarta/ws/rs/GE", recursive);
             assertFalse(jarFileScanner.hasNext(), "Unexpectedly found package 'jakarta.ws.rs.GE' in jakarta.ws.rs-api");
         }
diff --git a/docs/src/main/docbook/media.xml b/docs/src/main/docbook/media.xml
index 288b923..517b163 100644
--- a/docs/src/main/docbook/media.xml
+++ b/docs/src/main/docbook/media.xml
@@ -1753,8 +1753,8 @@
 
                         <programlisting language="java">// MediaType of the body part will be derived from the file.
 final List&lt;EntityPart&gt; multiPartEntity = new List&lt;&gt;();
-list.add(EntityPart.withFileName("file001.txt").content(new FileInputStream("file001.txt")).build());
-list.add(EntityPart.withFileName("mypom.xml").content(new FileInputStream("pom.xml")).build());
+list.add(EntityPart.withFileName("file001.txt").content(Files.newInputStream(Path.of("file001.txt"))).build());
+list.add(EntityPart.withFileName("mypom.xml").content(Files.newInputStream(Path.of("pom.xml"))).build());
 
 final GenericEntity&lt;List&lt;EntityPart&gt;&gt; genericEntity = new GenericEntity&lt;&gt;(list) {};
 final Entity entity = Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE);
diff --git a/examples/oauth-client-twitter/src/main/java/org/glassfish/jersey/examples/oauth/twitterclient/App.java b/examples/oauth-client-twitter/src/main/java/org/glassfish/jersey/examples/oauth/twitterclient/App.java
index 5d39bde..e0b6f77 100644
--- a/examples/oauth-client-twitter/src/main/java/org/glassfish/jersey/examples/oauth/twitterclient/App.java
+++ b/examples/oauth-client-twitter/src/main/java/org/glassfish/jersey/examples/oauth/twitterclient/App.java
@@ -17,7 +17,7 @@
 import java.io.OutputStream;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.List;
 import java.util.Properties;
 
@@ -145,7 +145,7 @@
     private static void loadSettings() {
         InputStream st = null;
         try {
-            st = Files.newInputStream(Paths.get(PROPERTIES_FILE_NAME));
+            st = Files.newInputStream(Path.of(PROPERTIES_FILE_NAME));
             PROPERTIES.load(st);
         } catch (final IOException e) {
             // ignore
@@ -178,7 +178,7 @@
     private static void storeSettings() {
         OutputStream st = null;
         try {
-            st = Files.newOutputStream(Paths.get(PROPERTIES_FILE_NAME));
+            st = Files.newOutputStream(Path.of(PROPERTIES_FILE_NAME));
             PROPERTIES.store(st, null);
         } catch (final IOException e) {
             // ignore
diff --git a/examples/osgi-helloworld-webapp/functional-test/src/test/java/org/glassfish/jersey/examples/helloworld/test/AbstractWebAppTest.java b/examples/osgi-helloworld-webapp/functional-test/src/test/java/org/glassfish/jersey/examples/helloworld/test/AbstractWebAppTest.java
index 404c63d..cfd299d 100644
--- a/examples/osgi-helloworld-webapp/functional-test/src/test/java/org/glassfish/jersey/examples/helloworld/test/AbstractWebAppTest.java
+++ b/examples/osgi-helloworld-webapp/functional-test/src/test/java/org/glassfish/jersey/examples/helloworld/test/AbstractWebAppTest.java
@@ -14,7 +14,7 @@
 import java.io.IOException;
 import java.net.URI;
 import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.security.AccessController;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -228,7 +228,7 @@
 
         try {
 
-            final BufferedReader reader = Files.newBufferedReader(Paths.get(felixPolicy));
+            final BufferedReader reader = Files.newBufferedReader(Path.of(felixPolicy));
             String line;
             final Set<String> cpiNames = new HashSet<String>();
 
diff --git a/examples/reload/src/main/java/org/glassfish/jersey/examples/reload/App.java b/examples/reload/src/main/java/org/glassfish/jersey/examples/reload/App.java
index 8e922b7..e28fe2d 100644
--- a/examples/reload/src/main/java/org/glassfish/jersey/examples/reload/App.java
+++ b/examples/reload/src/main/java/org/glassfish/jersey/examples/reload/App.java
@@ -18,7 +18,7 @@
 import java.nio.file.Files;
 import java.nio.file.FileSystems;
 import java.nio.file.Path;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.nio.file.StandardWatchEventKinds;
 import java.nio.file.WatchEvent;
 import java.nio.file.WatchKey;
@@ -72,10 +72,10 @@
             try {
                 watcher = FileSystems.getDefault().newWatchService();
 
-                Path srcDir = Paths.get("src/main/java/org/glassfish/jersey/examples/reload");
+                Path srcDir = Path.of("src/main/java/org/glassfish/jersey/examples/reload");
                 registerWatcher(watcher, srcDir);
 
-                Path configFilePath = Paths.get(".");
+                Path configFilePath = Path.of(".");
                 registerWatcher(watcher, configFilePath);
 
             } catch (IOException e) {
diff --git a/examples/reload/src/main/java/org/glassfish/jersey/examples/reload/compiler/JavaFile.java b/examples/reload/src/main/java/org/glassfish/jersey/examples/reload/compiler/JavaFile.java
index 2a789ff..5c2b57c 100644
--- a/examples/reload/src/main/java/org/glassfish/jersey/examples/reload/compiler/JavaFile.java
+++ b/examples/reload/src/main/java/org/glassfish/jersey/examples/reload/compiler/JavaFile.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -14,7 +14,7 @@
 import java.io.IOException;
 import java.net.URI;
 import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 
 import javax.tools.SimpleJavaFileObject;
 
@@ -47,7 +47,7 @@
     public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
 
         String filePath = path + File.separator + className.replace('.', '/') + Kind.SOURCE.extension;
-        final byte[] bytes = Files.readAllBytes(Paths.get(filePath));
+        final byte[] bytes = Files.readAllBytes(Path.of(filePath));
 
         return new String(bytes);
     }
diff --git a/examples/sse-twitter-aggregator/src/main/java/org/glassfish/jersey/examples/aggregator/App.java b/examples/sse-twitter-aggregator/src/main/java/org/glassfish/jersey/examples/aggregator/App.java
index a3e6788..ebde366 100644
--- a/examples/sse-twitter-aggregator/src/main/java/org/glassfish/jersey/examples/aggregator/App.java
+++ b/examples/sse-twitter-aggregator/src/main/java/org/glassfish/jersey/examples/aggregator/App.java
@@ -13,7 +13,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.HashMap;
 import java.util.Properties;
 import java.util.logging.Level;
@@ -144,7 +144,7 @@
         InputStream st = null;
         try {
             String homeDir = System.getProperty("user.home");
-            st = Files.newInputStream(Paths.get(homeDir, TWITTER_PROPERTIES_FILE_NAME));
+            st = Files.newInputStream(Path.of(homeDir, TWITTER_PROPERTIES_FILE_NAME));
             properties.load(st);
         } catch (IOException e) {
             // ignore
@@ -230,7 +230,7 @@
             try {
                 fileStream = webRootPath == null
                         ? App.class.getResourceAsStream(WEB_ROOT + uri)
-                        : Files.newInputStream(Paths.get(webRootPath, uri));
+                        : Files.newInputStream(Path.of(webRootPath, uri));
             } catch (IOException e) {
                 fileStream = null;
             }
diff --git a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientProducer.java b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientProducer.java
index d583419..1fbf420 100644
--- a/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientProducer.java
+++ b/ext/microprofile/mp-rest-client/src/main/java/org/glassfish/jersey/microprofile/restclient/RestClientProducer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -24,7 +24,7 @@
 import java.net.URI;
 import java.net.URL;
 import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.security.AccessController;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
@@ -350,7 +350,7 @@
             }
             return result;
         } else if (location.startsWith(FILE_LOCATION)) {
-            return Files.newInputStream(Paths.get(URI.create(location)));
+            return Files.newInputStream(Path.of(URI.create(location)));
         } else {
             throw new IllegalStateException("Location of keystore must start with either classpath: or file:, but is: "
                                                     + location
diff --git a/ext/mvc/src/main/java/org/glassfish/jersey/server/mvc/spi/AbstractTemplateProcessor.java b/ext/mvc/src/main/java/org/glassfish/jersey/server/mvc/spi/AbstractTemplateProcessor.java
index 79dd79c..b375afe 100644
--- a/ext/mvc/src/main/java/org/glassfish/jersey/server/mvc/spi/AbstractTemplateProcessor.java
+++ b/ext/mvc/src/main/java/org/glassfish/jersey/server/mvc/spi/AbstractTemplateProcessor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2024 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -22,7 +22,7 @@
 import java.io.Reader;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -182,7 +182,7 @@
             // File-system path.
             if (reader == null) {
                 try {
-                    reader = new InputStreamReader(Files.newInputStream(Paths.get(template)), encoding);
+                    reader = new InputStreamReader(Files.newInputStream(Path.of(template)), encoding);
                 } catch (final IOException ioe) {
                     // NOOP.
                 }
diff --git a/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/RunnerMojo.groovy b/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/RunnerMojo.groovy
index b04c36b..865afb7 100644
--- a/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/RunnerMojo.groovy
+++ b/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/RunnerMojo.groovy
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -23,7 +23,7 @@
 import org.apache.maven.project.MavenProject
 
 import java.nio.file.Files
-import java.nio.file.Paths
+import java.nio.file.Path
 import java.util.regex.Pattern
 
 /**
@@ -96,7 +96,7 @@
 
         def command = string.split(" +(?=((.*?(?<!\\\\)'){2})*[^']*\$)")
 
-        return command?.length > 0 && Files.exists(Paths.get(command[0])) ? command : ["sh"]
+        return command?.length > 0 && Files.exists(Path.of(command[0])) ? command : ["sh"]
     }
 
     abstract Map commonEnvironment()
@@ -184,8 +184,8 @@
             sb.append(System.lineSeparator())
             def matcher = Pattern.compile("(#![^\r\n]*)(.*)", Pattern.DOTALL).matcher(new String(shellContent))
             def string = matcher.matches() ? matcher.replaceFirst("\$1${sb.toString()}\$2") : sb.append(shellContent).toString()
-            Paths.get(scriptsDirectory).toFile().mkdirs()
-            def reExecutableShell = Paths.get(scriptsDirectory, Paths.get(shell).fileName.toString())
+            Path.of(scriptsDirectory).toFile().mkdirs()
+            def reExecutableShell = Path.of(scriptsDirectory, Path.of(shell).fileName.toString())
             Files.write(reExecutableShell, string.bytes)
             getLog().info("Re-executable shell written to: $reExecutableShell")
         } catch (Exception e) {
diff --git a/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/gf4/AbstractGlassfishRunnerMojo.groovy b/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/gf4/AbstractGlassfishRunnerMojo.groovy
index c72b020..9d8a6ba 100644
--- a/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/gf4/AbstractGlassfishRunnerMojo.groovy
+++ b/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/gf4/AbstractGlassfishRunnerMojo.groovy
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -22,7 +22,7 @@
 import org.codehaus.gmavenplus.mojo.AbstractGroovyMojo
 import org.glassfish.jersey.test.maven.runner.RunnerMojo
 
-import java.nio.file.Paths
+import java.nio.file.Path
 /**
  * Abstract class for all Glassfish4 related mojos.
  *
@@ -58,8 +58,8 @@
 
     @Override
     void execute() throws MojoExecutionException, MojoFailureException {
-        asHome = Paths.get(asHome).isAbsolute() ? asHome : Paths.get(distDir, distSubdir, asHome)
-        logFile = Paths.get(logFile).isAbsolute()? logFile : Paths.get(asHome, "domains", domain, "logs", logFile)
+        asHome = Path.of(asHome).isAbsolute() ? asHome : Path.of(distDir, distSubdir, asHome)
+        logFile = Path.of(logFile).isAbsolute()? logFile : Path.of(asHome, "domains", domain, "logs", logFile)
         executeRunner()
     }
 
diff --git a/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/tomcat/AbstractTomcatRunnerMojo.groovy b/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/tomcat/AbstractTomcatRunnerMojo.groovy
index d98b59d..2b041e8 100644
--- a/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/tomcat/AbstractTomcatRunnerMojo.groovy
+++ b/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/tomcat/AbstractTomcatRunnerMojo.groovy
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -22,7 +22,7 @@
 import org.codehaus.gmavenplus.mojo.AbstractGroovyMojo
 import org.glassfish.jersey.test.maven.runner.RunnerMojo
 
-import java.nio.file.Paths
+import java.nio.file.Path
 /**
  * Abstract class for all Tomcat related mojos.
  *
@@ -47,8 +47,8 @@
 
     @Override
     void execute() throws MojoExecutionException, MojoFailureException {
-        catalinaHome = Paths.get(catalinaHome).isAbsolute() ? catalinaHome : Paths.get(distDir, distSubdir, catalinaHome)
-        logFile = logFile ?: Paths.get(catalinaHome, "logs", "catalina.out").toString()
+        catalinaHome = Path.of(catalinaHome).isAbsolute() ? catalinaHome : Path.of(distDir, distSubdir, catalinaHome)
+        logFile = logFile ?: Path.of(catalinaHome, "logs", "catalina.out").toString()
         executeRunner()
     }
 
diff --git a/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/wls/AbstractWlsRunnerMojo.groovy b/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/wls/AbstractWlsRunnerMojo.groovy
index 3fa9ffd..6232472 100644
--- a/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/wls/AbstractWlsRunnerMojo.groovy
+++ b/test-framework/maven/container-runner-maven-plugin/src/main/groovy/org/glassfish/jersey/test/maven/runner/wls/AbstractWlsRunnerMojo.groovy
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -22,7 +22,7 @@
 import org.codehaus.gmavenplus.mojo.AbstractGroovyMojo
 import org.glassfish.jersey.test.maven.runner.RunnerMojo
 
-import java.nio.file.Paths
+import java.nio.file.Path
 
 /**
  * Abstract class for all Weblogic related mojos.
@@ -52,8 +52,8 @@
 
     @Override
     void execute() throws MojoExecutionException, MojoFailureException {
-        mwHome = Paths.get(mwHome).isAbsolute() ? mwHome : Paths.get(distDir, distSubdir, mwHome)
-        logFile = logFile ?: Paths.get(mwHome, domain, "wls.log").toString()
+        mwHome = Path.of(mwHome).isAbsolute() ? mwHome : Path.of(distDir, distSubdir, mwHome)
+        logFile = logFile ?: Path.of(mwHome, domain, "wls.log").toString()
         executeRunner()
     }
 
diff --git a/test-framework/memleak-test-common/src/main/java/org/glassfish/jersey/test/memleak/common/MemoryLeakUtils.java b/test-framework/memleak-test-common/src/main/java/org/glassfish/jersey/test/memleak/common/MemoryLeakUtils.java
index d519d3f..ecfe68e 100644
--- a/test-framework/memleak-test-common/src/main/java/org/glassfish/jersey/test/memleak/common/MemoryLeakUtils.java
+++ b/test-framework/memleak-test-common/src/main/java/org/glassfish/jersey/test/memleak/common/MemoryLeakUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -23,7 +23,7 @@
 import java.lang.reflect.Method;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.List;
 import java.util.regex.Pattern;
@@ -121,7 +121,7 @@
             throws InvocationTargetException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, IOException {
         conditionallyInitHotSpotDiagnosticMXBean();
         try {
-            java.nio.file.Files.deleteIfExists(Paths.get(fileName));
+            java.nio.file.Files.deleteIfExists(Path.of(fileName));
         } catch (IOException e) {
             // do nothing and try to go further
         }
diff --git a/tests/integration/jersey-2421/src/test/java/org/glassfish/jersey/tests/integration/jersey2421/Jersey2421Test.java b/tests/integration/jersey-2421/src/test/java/org/glassfish/jersey/tests/integration/jersey2421/Jersey2421Test.java
index bae7758..79be107 100644
--- a/tests/integration/jersey-2421/src/test/java/org/glassfish/jersey/tests/integration/jersey2421/Jersey2421Test.java
+++ b/tests/integration/jersey-2421/src/test/java/org/glassfish/jersey/tests/integration/jersey2421/Jersey2421Test.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -38,7 +38,6 @@
 import org.glassfish.jersey.media.multipart.FormDataMultiPart;
 import org.glassfish.jersey.media.multipart.MultiPart;
 import org.glassfish.jersey.media.multipart.MultiPartFeature;
-import org.glassfish.jersey.message.internal.NullOutputStream;
 import org.glassfish.jersey.message.internal.OutboundMessageContext;
 
 import org.junit.jupiter.api.Test;
@@ -61,7 +60,7 @@
                 request.setStreamProvider(new OutboundMessageContext.StreamProvider() {
                     @Override
                     public OutputStream getOutputStream(final int contentLength) throws IOException {
-                        return new NullOutputStream();
+                        return OutputStream.nullOutputStream();
                     }
                 });
                 request.writeEntity();
diff --git a/tests/integration/jersey-2794/src/test/java/org/glassfish/jersey/tests/integration/jersey2794/Jersey2794ITCase.java b/tests/integration/jersey-2794/src/test/java/org/glassfish/jersey/tests/integration/jersey2794/Jersey2794ITCase.java
index 80eca2d..ce9ccdc 100644
--- a/tests/integration/jersey-2794/src/test/java/org/glassfish/jersey/tests/integration/jersey2794/Jersey2794ITCase.java
+++ b/tests/integration/jersey-2794/src/test/java/org/glassfish/jersey/tests/integration/jersey2794/Jersey2794ITCase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -23,7 +23,6 @@
 import java.nio.file.FileVisitResult;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -104,7 +103,7 @@
 
     private int matchingTempFiles(final String tempDir) throws IOException {
         AtomicInteger count = new AtomicInteger(0);
-        Files.walkFileTree(Paths.get(tempDir), new SimpleFileVisitor<Path>() {
+        Files.walkFileTree(Path.of(tempDir), new SimpleFileVisitor<Path>() {
             @Override
             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                 if (file.getFileName().startsWith("MIME") && file.getFileName().endsWith("tmp")) {
diff --git a/tests/integration/jersey-2846/src/test/java/org/glassfish/jersey/tests/integration/jersey2846/Jersey2846ITCase.java b/tests/integration/jersey-2846/src/test/java/org/glassfish/jersey/tests/integration/jersey2846/Jersey2846ITCase.java
index 4286aef..6b37da0 100644
--- a/tests/integration/jersey-2846/src/test/java/org/glassfish/jersey/tests/integration/jersey2846/Jersey2846ITCase.java
+++ b/tests/integration/jersey-2846/src/test/java/org/glassfish/jersey/tests/integration/jersey2846/Jersey2846ITCase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -20,7 +20,6 @@
 import java.nio.file.FileVisitResult;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.Arrays;
@@ -124,7 +123,7 @@
 
     private int matchingTempFiles(final String tempDir) throws IOException {
         AtomicInteger count = new AtomicInteger(0);
-        Files.walkFileTree(Paths.get(tempDir), new SimpleFileVisitor<Path>() {
+        Files.walkFileTree(Path.of(tempDir), new SimpleFileVisitor<Path>() {
             @Override
             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                 Path name = file.getFileName();
diff --git a/tests/performance/jmx-client/src/main/java/org/glassfish/jersey/tests/performance/jmxclient/Main.java b/tests/performance/jmx-client/src/main/java/org/glassfish/jersey/tests/performance/jmxclient/Main.java
index 05391bc..ba18aae 100644
--- a/tests/performance/jmx-client/src/main/java/org/glassfish/jersey/tests/performance/jmxclient/Main.java
+++ b/tests/performance/jmx-client/src/main/java/org/glassfish/jersey/tests/performance/jmxclient/Main.java
@@ -80,6 +80,6 @@
     private static void writeResult(double resultValue, String propertiesFile) throws IOException {
         Properties resultProps = new Properties();
         resultProps.put("YVALUE", Double.toString(resultValue));
-        resultProps.store(Files.newOutputStream(Paths.get(propertiesFile)), null);
+        resultProps.store(Files.newOutputStream(Path.of(propertiesFile)), null);
     }
 }
diff --git a/tools/jersey-release-notes-maven-plugin/src/main/java/org/glassfish/jersey/tools/plugins/releasenotes/ReleaseNotesMojo.java b/tools/jersey-release-notes-maven-plugin/src/main/java/org/glassfish/jersey/tools/plugins/releasenotes/ReleaseNotesMojo.java
index eec3df2..1ddf887 100644
--- a/tools/jersey-release-notes-maven-plugin/src/main/java/org/glassfish/jersey/tools/plugins/releasenotes/ReleaseNotesMojo.java
+++ b/tools/jersey-release-notes-maven-plugin/src/main/java/org/glassfish/jersey/tools/plugins/releasenotes/ReleaseNotesMojo.java
@@ -33,7 +33,7 @@
 import java.io.IOException;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
-import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -172,12 +172,12 @@
                                           String releaseVersion, String releaseDate,
                                           String releaseNotesFilePath,
                                           Boolean dryRun, Log log) throws IOException {
-        if (Files.notExists(Paths.get(templateFilePath))) {
+        if (Files.notExists(Path.of(templateFilePath))) {
             log.warn(String.format("There is no source template file at the given location:%s", templateFilePath));
             return;
         }
         final List<String> notesLines = new ArrayList<>();
-        final List<String> lines = Files.readAllLines(Paths.get(templateFilePath), Charset.defaultCharset());
+        final List<String> lines = Files.readAllLines(Path.of(templateFilePath), Charset.defaultCharset());
         for (final String line : lines) {
             if (line.contains(RELEASE_DATE_PATTERN)) {
                 notesLines.add(line.replace(RELEASE_DATE_PATTERN, releaseDate));
@@ -197,8 +197,8 @@
         }
         if (Boolean.FALSE.equals(dryRun)) {
             log.info(String.format("Storing release notes to file %s/%s.html", releaseNotesFilePath, releaseVersion));
-            Files.createDirectories(Paths.get(releaseNotesFilePath));
-            Files.write(Paths.get(String.format("%s/%s.html", releaseNotesFilePath, releaseVersion)), notesLines, Charset.defaultCharset());
+            Files.createDirectories(Path.of(releaseNotesFilePath));
+            Files.write(Path.of(String.format("%s/%s.html", releaseNotesFilePath, releaseVersion)), notesLines, Charset.defaultCharset());
         } else {
             log.info("Prepared release notes are not stored to file due to dryRun mode");
             log.info(String.format("File path to store release notes is: %s/%s.html", releaseNotesFilePath, releaseVersion));