Pass Generic Type of OutboundResponse entity to MBW.

Signed-off-by: jansupol <jan.supol@oracle.com>
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientResponse.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientResponse.java
index 2801ed2..cd53d45 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/ClientResponse.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientResponse.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2025 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.InputStream;
 import java.io.OutputStream;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
 import java.net.URI;
 import java.util.Collections;
 import java.util.Map;
@@ -77,18 +78,19 @@
                         ByteArrayOutputStream baos = new ByteArrayOutputStream();
                         OutputStream stream = null;
                         try {
-                            try {
-                                stream = requestContext.getWorkers().writeTo(
-                                        entity, entity.getClass(), null, null, response.getMediaType(),
-                                        response.getMetadata(), requestContext.getPropertiesDelegate(), baos,
-                                        Collections.<WriterInterceptor>emptyList());
-                            } finally {
-                                if (stream != null) {
-                                    stream.close();
-                                }
-                            }
+                            final Type t = response instanceof OutboundJaxrsResponse
+                                    ? ((OutboundJaxrsResponse) response).getContext().getEntityType()
+                                    : null;
+                            stream = requestContext.getWorkers().writeTo(
+                                    entity, entity.getClass(), t, null, response.getMediaType(),
+                                    response.getMetadata(), requestContext.getPropertiesDelegate(), baos,
+                                    Collections.<WriterInterceptor>emptyList());
                         } catch (IOException e) {
                             // ignore
+                        } finally {
+                            if (stream != null) {
+                                stream.close();
+                            }
                         }
 
                         byteArrayInputStream = new ByteArrayInputStream(baos.toByteArray());
diff --git a/core-client/src/test/java/org/glassfish/jersey/client/AbortTest.java b/core-client/src/test/java/org/glassfish/jersey/client/AbortTest.java
new file mode 100644
index 0000000..e9be45d
--- /dev/null
+++ b/core-client/src/test/java/org/glassfish/jersey/client/AbortTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2025 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.client;
+
+import org.junit.jupiter.api.Test;
+
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientRequestFilter;
+import javax.ws.rs.core.GenericEntity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.MessageBodyWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+//import static java.nio.charset.StandardCharsets;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class AbortTest {
+    private static final String TEXT_CSV = "text/csv";
+    private static final String EXPECTED_CSV = "hello;goodbye\nsalutations;farewell";
+    private static final List<List<String>> CSV_LIST = Arrays.asList(
+            Arrays.asList("hello", "goodbye"),
+            Arrays.asList("salutations", "farewell")
+    );
+
+    @Test
+    void testAbortWithGenericEntity() {
+        Client client = ClientBuilder.newBuilder()
+                .register(AbortRequestFilter.class)
+                .register(CsvWriter.class)
+                .build();
+        String csvString = client.target("http://localhost:8080")
+                .request(TEXT_CSV)
+                .get(String.class);
+        assertEquals(EXPECTED_CSV, csvString);
+        client.close();
+    }
+
+    public static class AbortRequestFilter implements ClientRequestFilter {
+
+        @Override
+        public void filter(ClientRequestContext requestContext) {
+            requestContext.abortWith(Response.ok(new GenericEntity<List<List<String>>>(CSV_LIST) {
+            }).type(TEXT_CSV).build());
+        }
+    }
+
+    @Produces(TEXT_CSV)
+    public static class CsvWriter implements MessageBodyWriter<List<List<String>>> {
+
+        @Override
+        public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+            System.out.println(genericType.getTypeName());
+            return List.class.isAssignableFrom(type) && genericType instanceof ParameterizedType
+                    && ((ParameterizedType) genericType).getActualTypeArguments()[0] instanceof ParameterizedType
+                    && String.class.equals(((ParameterizedType) ((ParameterizedType) genericType).getActualTypeArguments()[0])
+                        .getActualTypeArguments()[0]);
+        }
+
+        @Override
+        public void writeTo(List<List<String>> csvList, Class<?> type, Type genericType, Annotation[] annotations,
+                            MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
+                throws IOException, WebApplicationException {
+            List<String> rows = new ArrayList<>();
+            for (List<String> row : csvList) {
+                rows.add(String.join(";", row));
+            }
+            String csv = String.join("\n", rows);
+
+            entityStream.write(csv.getBytes(StandardCharsets.UTF_8));
+            entityStream.flush();
+        }
+    }
+
+}