Merge pull request #1275 from mkarg/nio-path

Entity Provider for java.nio.file.Path
diff --git a/jaxrs-spec/src/main/asciidoc/chapters/appendix/_change-log.adoc b/jaxrs-spec/src/main/asciidoc/chapters/appendix/_change-log.adoc
index 716a214..b411cae 100644
--- a/jaxrs-spec/src/main/asciidoc/chapters/appendix/_change-log.adoc
+++ b/jaxrs-spec/src/main/asciidoc/chapters/appendix/_change-log.adoc
@@ -1,6 +1,6 @@
 ////
 *******************************************************************
-* Copyright (c) 2019, 2024 Eclipse Foundation
+* Copyright (c) 2019 Eclipse Foundation
 *
 * This specification document is made available under the terms
 * of the Eclipse Foundation Specification License v1.0, which is
@@ -12,6 +12,8 @@
 [[change-log]]
 == Change Log
 
+include::_changes-since-4.0-release.adoc[]
+
 include::_changes-since-3.1-release.adoc[]
 
 include::_changes-since-3.0-release.adoc[]
diff --git a/jaxrs-spec/src/main/asciidoc/chapters/appendix/_changes-since-4.0-release.adoc b/jaxrs-spec/src/main/asciidoc/chapters/appendix/_changes-since-4.0-release.adoc
new file mode 100644
index 0000000..ed3c003
--- /dev/null
+++ b/jaxrs-spec/src/main/asciidoc/chapters/appendix/_changes-since-4.0-release.adoc
@@ -0,0 +1,14 @@
+////
+*******************************************************************
+* Copyright (c) 2024 Eclipse Foundation
+*
+* This specification document is made available under the terms
+* of the Eclipse Foundation Specification License v1.0, which is
+* available at https://www.eclipse.org/legal/efsl.php.
+*******************************************************************
+////
+
+[[changes-since-4.0-release]]
+=== Changes Since 4.0 Release
+
+* <<standard_entity_providers>>: Added entity provider for `java.nio.file.Path`
diff --git a/jaxrs-spec/src/main/asciidoc/chapters/providers/_entity_providers.adoc b/jaxrs-spec/src/main/asciidoc/chapters/providers/_entity_providers.adoc
index 989168a..7a8ca81 100644
--- a/jaxrs-spec/src/main/asciidoc/chapters/providers/_entity_providers.adoc
+++ b/jaxrs-spec/src/main/asciidoc/chapters/providers/_entity_providers.adoc
@@ -1,6 +1,6 @@
 ////
 *******************************************************************
-* Copyright (c) 2019, 2021 Eclipse Foundation
+* Copyright (c) 2019 Eclipse Foundation
 *
 * This specification document is made available under the terms
 * of the Eclipse Foundation Specification License v1.0, which is
@@ -138,6 +138,8 @@
   All media types (`\*/*`).
 `java.io.File`::
   All media types (`\*/*`).
+`java.nio.file.Path`::
+  All media types (`\*/*`).
 `jakarta.activation.DataSource`::
   All media types (`\*/*`).
 `javax.xml.transform.Source`::
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsink/MBWCheckResource.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsink/MBWCheckResource.java
index 5eca3f8..4bf16bd 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsink/MBWCheckResource.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsink/MBWCheckResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017 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
@@ -134,6 +134,28 @@
   }
 
   @GET
+  @Path("path")
+  @Produces(MediaType.SERVER_SENT_EVENTS)
+  public void sendPath(@Context SseEventSink sink, @Context Sse sse) {
+    java.nio.file.Path p;
+    try (SseEventSink s = sink) {
+      try {
+        p = Files.createTempFile("tck", "temppath");
+        Files.write(p, MESSAGE.getBytes(), StandardOpenOption.CREATE,
+            StandardOpenOption.APPEND);
+        p.toFile().deleteOnExit();
+        s.send(sse.newEventBuilder().data(p).mediaType(MediaType.WILDCARD_TYPE)
+            .build());
+      } catch (IOException e) {
+        s.send(sse.newEvent(e.getMessage()));
+        throw new RuntimeException(e); // log to server log
+      }
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
+    }
+  }
+
+  @GET
   @Path("inputstream")
   @Produces(MediaType.SERVER_SENT_EVENTS)
   public void sendInputStream(@Context SseEventSink sink, @Context Sse sse) {
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/filter/interceptor/JAXRSClientIT.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/filter/interceptor/JAXRSClientIT.java
index a258a9c..6246d2b 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/filter/interceptor/JAXRSClientIT.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/filter/interceptor/JAXRSClientIT.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 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,6 +22,7 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.InputStream;
+import java.nio.file.Files;
 
 import javax.xml.namespace.QName;
 
@@ -620,6 +621,105 @@
     logMsg("JAXRS called registered writer interceptor for file provider");
   }
 
+  // ------------------------- Path -----------------------------------
+
+  /*
+   * @testName: pathReaderContainerInterceptorTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:84;
+   * 
+   * @test_Strategy: JAX-RS implementations are REQUIRED to call registered
+   * interceptors when mapping representations to Java types and vice versa.
+   */
+  @Test
+  public void pathReaderContainerInterceptorTest() throws Fault {
+    addInterceptors(EntityReaderInterceptor.class);
+    setProperty(Property.REQUEST, buildRequest(Request.POST, "postpath"));
+    setRequestContentEntity(content);
+    setProperty(Property.SEARCH_STRING,
+        EntityReaderInterceptor.class.getName());
+    setProperty(Property.UNEXPECTED_RESPONSE_MATCH, Resource.DIRECTION);
+    invoke();
+    logMsg("JAXRS called registered reader interceptor for path provider");
+  }
+
+  /*
+   * @testName: pathReaderNoInterceptorTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:84;
+   * 
+   * @test_Strategy: JAX-RS implementations are REQUIRED to call registered
+   * interceptors when mapping representations to Java types and vice versa.
+   */
+  @Test
+  public void pathReaderNoInterceptorTest() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(Request.POST, "postpath"));
+    setRequestContentEntity(content);
+    setProperty(Property.SEARCH_STRING, content);
+    invoke();
+  }
+
+  /*
+   * @testName: pathWriterContainerInterceptorTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:84;
+   * 
+   * @test_Strategy: JAX-RS implementations are REQUIRED to call registered
+   * interceptors when mapping representations to Java types and vice versa.
+   */
+  @Test
+  public void pathWriterContainerInterceptorTest() throws Fault {
+    addInterceptors(EntityWriterInterceptor.class);
+    setProperty(Property.REQUEST, buildRequest(Request.GET, "getpath"));
+    setProperty(Property.SEARCH_STRING,
+        EntityWriterInterceptor.class.getName());
+    setProperty(Property.SEARCH_STRING, Resource.DIRECTION);
+    invoke();
+    logMsg("JAXRS called registered writer interceptor for path provider");
+  }
+
+  /*
+   * @testName: pathWriterNoInterceptorTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:84;
+   * 
+   * @test_Strategy: JAX-RS implementations are REQUIRED to call registered
+   * interceptors when mapping representations to Java types and vice versa.
+   */
+  @Test
+  public void pathWriterNoInterceptorTest() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(Request.GET, "getpath"));
+    setProperty(Property.SEARCH_STRING, Resource.getName());
+    invoke();
+  }
+
+  /*
+   * @testName: pathWriterClientInterceptorTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:84;
+   * 
+   * @test_Strategy: JAX-RS implementations are REQUIRED to call registered
+   * interceptors when mapping representations to Java types and vice versa.
+   */
+  @Test
+  public void pathWriterClientInterceptorTest() throws Fault {
+    try {
+      java.nio.file.Path path = Files.createTempFile("temp", "tmp");
+      Files.writeString(path, content);
+      setRequestContentEntity(path);
+    } catch (IOException e) {
+      throw new Fault(e);
+    }
+    addProvider(EntityWriterInterceptor.class);
+    addInterceptors(EntityWriterInterceptor.class);
+    setProperty(Property.REQUEST, buildRequest(Request.POST, "poststring"));
+    setProperty(Property.SEARCH_STRING,
+        EntityWriterInterceptor.class.getName());
+    setProperty(Property.UNEXPECTED_RESPONSE_MATCH, Resource.DIRECTION);
+    invoke();
+    logMsg("JAXRS called registered writer interceptor for path provider");
+  }
+
   // ------------------------- DataSource -----------------------------------
 
   /*
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/filter/interceptor/Resource.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/filter/interceptor/Resource.java
index 5597822..e65c9e2 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/filter/interceptor/Resource.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/filter/interceptor/Resource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013 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,6 +23,7 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.file.Files;
 import java.util.List;
 
 import javax.xml.namespace.QName;
@@ -134,6 +135,21 @@
   }
 
   @GET
+  @Path("getpath")
+  public Response getPath() throws IOException {
+    java.nio.file.Path path = Files.createTempFile("filter", "tmp");
+    Files.writeString(path, getName());
+    return buildResponse(path);
+  }
+
+  @POST
+  @Path("postpath")
+  public Response postPath(java.nio.file.Path path) throws IOException {
+    String text = Files.readString(path);
+    return buildResponse(text);
+  }
+
+  @GET
   @Path("getdatasource")
   public Response getDataSource() {
     StringDataSource source = new StringDataSource(getName(),
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/JAXRSClientIT.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/JAXRSClientIT.java
index 1dbd47b..152742b 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/JAXRSClientIT.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/JAXRSClientIT.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 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
@@ -82,7 +82,7 @@
   }
 
   String[] methodsAll = { "bytearray", "string", "inputstream", "reader",
-      "file", "datasource", "source", "jaxb", "streamingoutput" };
+      "file", "path", "datasource", "source", "jaxb", "streamingoutput" };
 
  
   @Deployment(testable = false)
@@ -94,7 +94,7 @@
       AbstractProvider.class, TckBooleanProvider.class, 
       TckByteArrayProvider.class, TckCharacterProvider.class, 
       TckDataSourceProvider.class, TckDataSourceProvider.class, 
-      TckFileProvider.class, TckInputStreamProvider.class, 
+      TckFileProvider.class, TckPathProvider.class, TckInputStreamProvider.class, 
       TckJaxbProvider.class, TckMapProvider.class, 
       TckNumberProvider.class, TckReaderProvider.class, 
       TckSourceProvider.class, TckStreamingOutputProvider.class, 
@@ -196,6 +196,22 @@
   }
 
   /*
+   * @testName: readWritePathProviderTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:35
+   * 
+   * @test_Strategy: An implementation MUST support application-provided entity
+   * providers and MUST use those in preference to its own pre-packaged
+   * providers when either could handle the same request.
+   * 
+   */
+  @Test
+  @Tag("xml_binding")
+  public void readWritePathProviderTest() throws Fault {
+    setPropertyAndInvoke("path", MediaType.APPLICATION_XML_TYPE);
+  }
+
+  /*
    * @testName: readWriteDataSourceProviderTest
    * 
    * @assertion_ids: JAXRS:SPEC:35
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/Resource.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/Resource.java
index 6652ef1..548a891 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/Resource.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/Resource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 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
@@ -63,6 +63,12 @@
     return file;
   }
 
+  @Path("path")
+  @POST
+  public java.nio.file.Path path(java.nio.file.Path path) {
+    return path;
+  }
+
   @Path("datasource")
   @POST
   public DataSource datasource(DataSource datasource) {
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/TSAppConfig.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/TSAppConfig.java
index 8381daa..98ecc14 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/TSAppConfig.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/TSAppConfig.java
@@ -29,6 +29,7 @@
     resources.add(TckByteArrayProvider.class);
     resources.add(TckDataSourceProvider.class);
     resources.add(TckFileProvider.class);
+    resources.add(TckPathProvider.class);
     resources.add(TckInputStreamProvider.class);
     resources.add(TckJaxbProvider.class);
     resources.add(TckMapProvider.class);
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/TckPathProvider.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/TckPathProvider.java
new file mode 100644
index 0000000..12e18ea
--- /dev/null
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/overridestandard/TckPathProvider.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2024 Markus Karg. 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 ee.jakarta.tck.ws.rs.spec.provider.overridestandard;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class TckPathProvider extends AbstractProvider
+    implements MessageBodyReader<Path>, MessageBodyWriter<Path> {
+
+  @Override
+  public boolean isWriteable(Class<?> type, Type genericType,
+      Annotation[] annotations, MediaType mediaType) {
+    return type == Path.class;
+  }
+
+  @Override
+  public long getSize(Path t, Class<?> type, Type genericType,
+      Annotation[] annotations, MediaType mediaType) {
+    return getLength();
+  }
+
+  @Override
+  public void writeTo(Path t, Class<?> type, Type genericType,
+      Annotation[] annotations, MediaType mediaType,
+      MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
+      throws IOException, WebApplicationException {
+    String text = Files.readString(t);
+    entityStream.write(text == null ? "".getBytes() : text.getBytes());
+    entityStream.write(getWriterName().getBytes());
+  }
+
+  @Override
+  public boolean isReadable(Class<?> type, Type genericType,
+      Annotation[] annotations, MediaType mediaType) {
+    return isWriteable(type, genericType, annotations, mediaType);
+  }
+
+  @Override
+  public Path readFrom(Class<Path> type, Type genericType,
+      Annotation[] annotations, MediaType mediaType,
+      MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+      throws IOException, WebApplicationException {
+    Path p = Files.createTempFile("tckjaxrs", "tmp");
+    Files.writeString(p, getReaderName());
+    return p;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standard/JAXRSClientIT.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standard/JAXRSClientIT.java
index df778ab..4cbb644 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standard/JAXRSClientIT.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standard/JAXRSClientIT.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 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
@@ -151,7 +151,7 @@
   }
 
 
-  String[] methodsAll = { "bytearray", "string", "inputstream", "file",
+  String[] methodsAll = { "bytearray", "string", "inputstream", "file", "path",
       "datasource", "streamingoutput" };
 
   /* Run test */
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standard/Resource.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standard/Resource.java
index e693482..cc5ab1a 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standard/Resource.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standard/Resource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 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
@@ -110,6 +110,12 @@
     return file;
   }
 
+  @Path("path")
+  @POST
+  public java.nio.file.Path file(java.nio.file.Path path) {
+    return path;
+  }
+
   @Path("datasource")
   @POST
   public DataSource datasource(DataSource datasource) {
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standardnotnull/JAXRSClientIT.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standardnotnull/JAXRSClientIT.java
index 767652c..170672a 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standardnotnull/JAXRSClientIT.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standardnotnull/JAXRSClientIT.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 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
@@ -21,6 +21,7 @@
 import java.io.Reader;
 import java.math.BigDecimal;
 import java.io.IOException;
+import java.nio.file.Files;
 
 import javax.xml.transform.Source;
 
@@ -311,6 +312,53 @@
   }
 
   /*
+   * @testName: serverPathProviderTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:33; JAXRS:SPEC:33.5; JAXRS:SPEC:75;
+   * 
+   * @test_Strategy: java.nio.file.Path All media types.
+   * 
+   * When reading zero-length request entities, all implementation-supplied
+   * MessageBodyReader implementations except the JAXB-related one MUST create a
+   * corresponding Java object that represents zero-length data; they MUST NOT
+   * return null.
+   */
+  @Test
+  @Tag("xml_binding")
+  public void serverPathProviderTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, Resource.NOTNULL);
+    setProperty(Property.REQUEST, buildRequest(Request.POST, "path"));
+    invoke();
+  }
+
+  /*
+   * @testName: clientPathProviderTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:863;
+   * 
+   * @test_Strategy: java.io.File All media types.
+   * 
+   * for a zero-length response entities returns null or a corresponding Java
+   * object that represents zero-length data.
+   */
+  @Test
+  @Tag("xml_binding")
+  public void clientPathProviderTest() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(Request.GET, "entity"));
+    invoke();
+    java.nio.file.Path entity = getResponseBody(java.nio.file.Path.class);
+    String content = null;
+    if (entity != null)
+      try {
+        content = Files.readString(entity);
+      } catch (Exception e) {
+        throw new Fault(e);
+      }
+    assertTrue(content == null || content.length() == 0,
+        "Path reader gets unexpected"+ content);
+  }
+
+  /*
    * @testName: serverDataSourceProviderTest
    * 
    * @assertion_ids: JAXRS:SPEC:33; JAXRS:SPEC:33.6; JAXRS:SPEC:75;
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standardnotnull/Resource.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standardnotnull/Resource.java
index 31e9e3d..cad71b8 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standardnotnull/Resource.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/spec/provider/standardnotnull/Resource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 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
@@ -72,6 +72,12 @@
     return isNull(file);
   }
 
+  @Path("path")
+  @POST
+  public String path(java.nio.file.Path path) {
+    return isNull(path);
+  }
+
   @Path("datasource")
   @POST
   public String datasource(DataSource datasource) {