Add changes from 4.0 PR 863
diff --git a/examples/src/main/java/jaxrs/examples/sse/ServerSentEventsResource.java b/examples/src/main/java/jaxrs/examples/sse/ServerSentEventsResource.java
index a4c0818..de70e8d 100644
--- a/examples/src/main/java/jaxrs/examples/sse/ServerSentEventsResource.java
+++ b/examples/src/main/java/jaxrs/examples/sse/ServerSentEventsResource.java
@@ -98,7 +98,10 @@
                 sseEventSink.close();
             } catch (final InterruptedException e) {
                 e.printStackTrace();
+            } catch (IOException ioe) {
+                //handle I/O error
             }
+
         });
     }
 }
diff --git a/jaxrs-api/src/main/java/jakarta/ws/rs/sse/SseEventSink.java b/jaxrs-api/src/main/java/jakarta/ws/rs/sse/SseEventSink.java
index 6513a92..cb214e6 100644
--- a/jaxrs-api/src/main/java/jakarta/ws/rs/sse/SseEventSink.java
+++ b/jaxrs-api/src/main/java/jakarta/ws/rs/sse/SseEventSink.java
@@ -16,6 +16,7 @@
 
 package jakarta.ws.rs.sse;
 
+import java.io.IOException;
 import java.util.concurrent.CompletionStage;
 
 /**
@@ -71,7 +72,8 @@
      * <p>
      * Subsequent calls have no effect and are ignored. Once the {@link SseEventSink} is closed, invoking any method other
      * than this one and {@link #isClosed()} would result in an {@link IllegalStateException} being thrown.
+     * @throws  IOException  if an I/O error occurs.
      */
     @Override
-    void close();
+    void close() throws IOException;
 }
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsink/CloseResource.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsink/CloseResource.java
index 916bfff..55e3f68 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsink/CloseResource.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsink/CloseResource.java
@@ -25,6 +25,9 @@
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.sse.Sse;
 import jakarta.ws.rs.sse.SseEventSink;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 @Path("close")
 public class CloseResource {
@@ -33,6 +36,8 @@
 
   private static volatile boolean isClosed = false;
 
+  private static final Logger LOG = Logger.getLogger(CloseResource.class.getName());
+
   @GET
   @Path("reset")
   @Produces(MediaType.SERVER_SENT_EVENTS)
@@ -41,6 +46,8 @@
     isClosed = false;
     try (SseEventSink s = sink) {
       s.send(sse.newEvent("RESET"));
+    } catch (IOException e) {
+      throw new RuntimeException(e);
     }
   }
 
@@ -52,15 +59,19 @@
       public void run() {
         SseEventSink s = sink;
         s.send(sse.newEvent(SSEMessage.MESSAGE));
-        s.close();
-        isClosed = s.isClosed();
-        if (!isClosed)
-          return;
-        s.close();
-        isClosed = s.isClosed();
-        if (!isClosed)
-          return;
-        s.close();
+        try {
+          s.close();
+          isClosed = s.isClosed();
+          if (!isClosed)
+            return;
+          s.close();
+          isClosed = s.isClosed();
+          if (!isClosed)
+            return;
+          s.close();
+        } catch (IOException e) {
+          //ignore this exception and isClosed will be checked later.
+        }
         isClosed = s.isClosed();
         if (!isClosed)
           return;
@@ -88,6 +99,8 @@
         return;
       }
       s.send(sse.newEvent("CHECK"));
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
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 4e9c597..b646184 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
@@ -16,6 +16,7 @@
 
 package ee.jakarta.tck.ws.rs.jaxrs21.ee.sse.sseeventsink;
 
+import ee.jakarta.tck.ws.rs.jaxrs21.ee.sse.sseeventsource.ServiceUnavailableResource;
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
@@ -23,6 +24,8 @@
 import java.nio.file.Files;
 import java.nio.file.StandardOpenOption;
 
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import javax.xml.namespace.QName;
 
 import ee.jakarta.tck.ws.rs.common.impl.SinglevaluedMap;
@@ -46,7 +49,7 @@
 @Path("mbw")
 public class MBWCheckResource {
   static final String MESSAGE = SSEMessage.MESSAGE;
-
+  private static final Logger LOG = Logger.getLogger(MBWCheckResource.class.getName());
   @GET
   @Path("boolean")
   @Produces(MediaType.SERVER_SENT_EVENTS)
@@ -54,6 +57,8 @@
     try (SseEventSink s = sink) {
       s.send(sse.newEventBuilder().data(true)
           .mediaType(MediaType.TEXT_PLAIN_TYPE).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -64,6 +69,8 @@
     try (SseEventSink s = sink) {
       s.send(sse.newEventBuilder().data(MESSAGE.getBytes())
           .mediaType(MediaType.WILDCARD_TYPE).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -74,6 +81,8 @@
     try (SseEventSink s = sink) {
       s.send(sse.newEventBuilder().data(MESSAGE.charAt(0))
           .mediaType(MediaType.TEXT_PLAIN_TYPE).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -85,6 +94,8 @@
       s.send(sse.newEventBuilder()
           .data(new StringDataSource(MESSAGE, MediaType.TEXT_PLAIN_TYPE))
           .mediaType(MediaType.WILDCARD_TYPE).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -95,6 +106,8 @@
     try (SseEventSink s = sink) {
       s.send(sse.newEventBuilder().data(Double.MAX_VALUE)
           .mediaType(MediaType.TEXT_PLAIN_TYPE).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -115,6 +128,8 @@
         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);
     }
   }
 
@@ -126,6 +141,8 @@
       s.send(sse.newEventBuilder()
           .data(new ByteArrayInputStream(MESSAGE.getBytes()))
           .mediaType(MediaType.WILDCARD_TYPE).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -136,6 +153,8 @@
     try (SseEventSink s = sink) {
       s.send(sse.newEventBuilder().data(Integer.MIN_VALUE)
           .mediaType(MediaType.TEXT_PLAIN_TYPE).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -148,6 +167,8 @@
           String.class, MESSAGE);
       s.send(sse.newEventBuilder().data(element)
           .mediaType(MediaType.APPLICATION_XML_TYPE).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -160,6 +181,8 @@
       map.add("name", MESSAGE);
       s.send(sse.newEventBuilder().data(map)
           .mediaType(MediaType.APPLICATION_FORM_URLENCODED_TYPE).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -172,6 +195,8 @@
           .data(new InputStreamReader(
               new ByteArrayInputStream(MESSAGE.getBytes())))
           .mediaType(MediaType.WILDCARD_TYPE).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -184,6 +209,8 @@
       StringStreamingOutput output = new StringStreamingOutput(MESSAGE);
       s.send(sse.newEventBuilder().data(output)
           .mediaType(MediaType.WILDCARD_TYPE).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -194,6 +221,8 @@
     try (SseEventSink s = sink) {
       s.send(sse.newEventBuilder().data(MESSAGE)
           .mediaType(MediaType.WILDCARD_TYPE).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -205,6 +234,8 @@
     try (SseEventSink s = sink) {
       s.send(sse.newEventBuilder().data(new StringSource(MESSAGE))
           .mediaType(MediaType.TEXT_XML_TYPE).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 }
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsink/StageCheckerResource.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsink/StageCheckerResource.java
index dd51b8a..3753fc3 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsink/StageCheckerResource.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsink/StageCheckerResource.java
@@ -18,6 +18,7 @@
 
 import static ee.jakarta.tck.ws.rs.jaxrs21.ee.sse.SSEJAXRSClient.MESSAGE;
 
+import java.io.IOException;
 import java.util.concurrent.CompletableFuture;
 
 import jakarta.ws.rs.GET;
@@ -34,7 +35,7 @@
 
   @GET
   @Produces(MediaType.SERVER_SENT_EVENTS)
-  public void send(@Context SseEventSink sink, @Context Sse sse) {
+  public void send(@Context SseEventSink sink, @Context Sse sse) throws IOException{
     try (SseEventSink s = sink) {
       CompletableFuture<?> stage = s.send(sse.newEvent(MESSAGE))
           .toCompletableFuture();
@@ -48,6 +49,8 @@
         }
       }
       s.send(sse.newEvent(DONE));
+    } catch (IOException e) {
+      e.printStackTrace();
     }
   }
 }
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsource/MediaTypeResource.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsource/MediaTypeResource.java
index f8b6ff1..1db5010 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsource/MediaTypeResource.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsource/MediaTypeResource.java
@@ -16,6 +16,9 @@
 
 package ee.jakarta.tck.ws.rs.jaxrs21.ee.sse.sseeventsource;
 
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import javax.xml.namespace.QName;
 
 import ee.jakarta.tck.ws.rs.common.impl.JaxbKeyValueBean;
@@ -31,11 +34,11 @@
 import jakarta.ws.rs.sse.Sse;
 import jakarta.ws.rs.sse.SseEventSink;
 import jakarta.xml.bind.JAXBElement;
-
+import java.util.logging.Logger;
 @Path("media")
 public class MediaTypeResource {
   private static MediaType mediaType = MediaType.WILDCARD_TYPE;
-
+  private static final Logger LOG = Logger.getLogger(MediaTypeResource.class.getName());
   @POST
   @Path("set")
   public String setMediaType(String media) {
@@ -51,6 +54,8 @@
     try (SseEventSink s = sink) {
       s.send(sse.newEventBuilder().data(SSEMessage.MESSAGE).mediaType(mediaType)
           .build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -62,6 +67,8 @@
       JAXBElement<String> element = new JAXBElement<String>(new QName("name"),
           String.class, SSEMessage.MESSAGE);
       s.send(sse.newEventBuilder().data(element).mediaType(mediaType).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -73,6 +80,8 @@
       JaxbKeyValueBean bean = new JaxbKeyValueBean();
       bean.set("key", SSEMessage.MESSAGE);
       s.send(sse.newEventBuilder().data(bean).mediaType(mediaType).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -84,6 +93,8 @@
       SinglevaluedMap<String, String> map = new SinglevaluedMap<>();
       map.add("key", SSEMessage.MESSAGE);
       s.send(sse.newEventBuilder().data(map).mediaType(mediaType).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 }
diff --git a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsource/ServiceUnavailableResource.java b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsource/ServiceUnavailableResource.java
index 4b1cb85..cc03d2b 100644
--- a/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsource/ServiceUnavailableResource.java
+++ b/jaxrs-tck/src/main/java/ee/jakarta/tck/ws/rs/jaxrs21/ee/sse/sseeventsource/ServiceUnavailableResource.java
@@ -31,6 +31,9 @@
 import jakarta.ws.rs.sse.OutboundSseEvent;
 import jakarta.ws.rs.sse.Sse;
 import jakarta.ws.rs.sse.SseEventSink;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 @Path("su")
 public class ServiceUnavailableResource {
@@ -44,6 +47,8 @@
 
   static final String MESSAGE = SSEMessage.MESSAGE;
 
+  private static final Logger LOG = Logger.getLogger(ServiceUnavailableResource.class.getName());
+
   @GET
   @Path("reset")
   public String reset() {
@@ -105,6 +110,8 @@
       } else {
         try (SseEventSink s = sink) {
           s.send(sse.newEvent(MESSAGE));
+        } catch (IOException e) {
+          LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
         }
       }
     }
@@ -118,7 +125,11 @@
       count++;
       if (isConnectionLost != 0) {
         isConnectionLost--;
-        sink.close();
+        try {
+          sink.close();
+        } catch (IOException e) {
+          e.printStackTrace();
+        }
         /*
          * To cancel a stream from the server, respond with a non
          * "text/event-stream" Content-Type or return an HTTP status other than
@@ -127,6 +138,8 @@
       } else {
         try (SseEventSink s = sink) {
           s.send(sse.newEvent(MESSAGE));
+        } catch (IOException e) {
+          LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
         }
       }
     }
@@ -138,6 +151,8 @@
   public void sendRetry(@Context SseEventSink sink, @Context Sse sse) {
     try (SseEventSink s = sink) {
       s.send(sse.newEventBuilder().data(MESSAGE).reconnectDelay(3000L).build());
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 
@@ -148,6 +163,8 @@
     try (SseEventSink s = sink) {
       s.send(
           (OutboundSseEvent) new OutboundSSEEventImpl(MESSAGE).setDelay(20000));
+    } catch (IOException e) {
+      LOG.log(Level.WARNING, "Failed to close SseEventSink", e);
     }
   }
 }