Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2025 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2026 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
Expand Down Expand Up @@ -83,7 +83,7 @@ private class CompletedAsyncContextListener implements AsyncListener {

@Override
public void onComplete(AsyncEvent event) throws IOException {
complete();
completed.set(true);
}

@Override
Expand All @@ -93,7 +93,7 @@ public void onTimeout(AsyncEvent event) throws IOException {

@Override
public void onError(AsyncEvent event) throws IOException {
complete();
completed.set(true);
}

@Override
Expand Down
58 changes: 58 additions & 0 deletions tests/integration/jersey-6044/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright (c) 2026 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

-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>project</artifactId>
<groupId>org.glassfish.jersey.tests.integration</groupId>
<version>3.1.99-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>jersey-6044</artifactId>

<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-http</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.ee10</groupId>
<artifactId>jetty-ee10-servlet</artifactId>
<version>${jetty.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-bundle</artifactId>
<type>pom</type>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2026 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.tests.jettyresponseclose;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.container.AsyncResponse;
import jakarta.ws.rs.container.Suspended;
import jakarta.ws.rs.core.Response;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Path("/get-me-204")
public class Resource204 {
private static final ScheduledExecutorService executor = Executors.newScheduledThreadPool(100);

@GET
public void get(@Suspended final AsyncResponse ar) {
executor.schedule(() -> {
ar.resume(Response.noContent().build());
}, 50, TimeUnit.MILLISECONDS);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* Copyright (c) 2026 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.tests.jettyresponseclose;

import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.core.Response;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.StatisticsHandler;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletContainer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class JettyHttpContainerDuringShutdownTest {

private static Server server;
private static final String URL = "http://localhost:9080/test/get-me-204";

@BeforeAll
public static void setup() throws Exception {
ResourceConfig resourceConfig = new ResourceConfig(Collections.singleton(Resource204.class));
ServletContextHandler ctx = new ServletContextHandler();
ServletHolder servlet = new ServletHolder(new ServletContainer(resourceConfig));
ctx.addServlet(servlet, "/test/*");
ContextHandlerCollection handlers = new ContextHandlerCollection();
server = new Server();

handlers.addHandler(ctx);
StatisticsHandler statisticsHandler = new StatisticsHandler();
statisticsHandler.setHandler(handlers);
server.setHandler(statisticsHandler);

ServerConnector http = new ServerConnector(server, new HttpConnectionFactory(new HttpConfiguration()));
http.setPort(9080);
server.addConnector(http);
server.setStopTimeout(50);
server.start();

waitStartUp();
}

private static void waitStartUp() {
for (int i = 0; i < 10; i++) {
try {
Response response = ClientBuilder.newClient().target(URL).request().get();
if (response.getStatus() == 204) {
return;
}
} catch (Throwable ignore) {
}
}
}

@AfterAll
public static void shutdown() throws Exception {
if (server != null) {
try {
server.stop();
server = null;
} catch (Throwable ignore) {
}
}
}

@Test
public void testResponseClose() throws Exception {
Client client = ClientBuilder.newClient();
try {
List<Future<Response>> waitingResponses = new ArrayList<>();
for (int i = 0; i < 100; i++) {
waitingResponses.add(client.target(URL).request().async().get());
}
shutdown();
for (Future<Response> responseFuture : waitingResponses) {
Response response = responseFuture.get(30, TimeUnit.SECONDS);
response.close();
Assertions.assertNotEquals(200, response.getStatus());
if (response.getStatus() / 100 != 2 && response.getStatus() / 100 != 5) {
Assertions.fail("Unexpected response code: " + response.getStatus());
}
}
} finally {
try {
client.close();
} catch (Throwable ignored) {
}
}
}
}
45 changes: 45 additions & 0 deletions tests/integration/jersey-6044/src/test/resources/surefire.policy
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2026 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
*/

// we do not care about java lib itself
grant codebase "file:${java.home}/-" {
permission java.security.AllPermission;
};

// we do not care about our dependencies
grant codebase "file:${settings.localRepository}/-" {
permission java.security.AllPermission;
};

grant codebase "file:${user.home}/-" {
permission java.io.FilePermission "<<ALL FILES>>", "read";
};

grant {
permission java.lang.management.ManagementPermission "monitor";
permission java.util.PropertyPermission "*", "read, write";
permission java.util.logging.LoggingPermission "control";
permission java.lang.RuntimePermission "setIO";
permission java.lang.reflect.ReflectPermission "suppressAccessChecks";

permission java.lang.RuntimePermission "accessDeclaredMembers";
permission java.lang.RuntimePermission "modifyThread";
permission java.io.FilePermission "<<ALL FILES>>", "read";

permission java.lang.RuntimePermission "getenv.JETTY_AVAILABLE_PROCESSORS";
permission java.net.SocketPermission "localhost", "accept,connect,listen,resolve";
permission java.lang.RuntimePermission "setContextClassLoader";
};
4 changes: 3 additions & 1 deletion tests/integration/pom.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright (c) 2011, 2025 Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2011, 2026 Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2018 Payara Foundation and/or its affiliates. All rights reserved.

This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -60,6 +60,7 @@
<module>jersey-4722</module>
<module>jersey-5087</module>
<module>jersey-5796</module>
<module>jersey-6044</module>
<module>microprofile</module>
<module>property-check</module>
<module>reactive-streams</module>
Expand Down Expand Up @@ -161,6 +162,7 @@
<module>jersey-2892</module>
<module>jersey-3796</module>
<module>jersey-4949</module>
<module>jersey-6044</module>
<module>resteasy-client</module>
<module>security-digest</module>
<module>servlet-2.5-autodiscovery-1</module>
Expand Down