Skip to content

Commit 77ab7da

Browse files
jbescosjansupol
authored andcommitted
Added extra tests
1 parent 214885b commit 77ab7da

File tree

3 files changed

+220
-1
lines changed

3 files changed

+220
-1
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
5+
6+
This program and the accompanying materials are made available under the
7+
terms of the Eclipse Public License v. 2.0, which is available at
8+
http://www.eclipse.org/legal/epl-2.0.
9+
10+
This Source Code may also be made available under the following Secondary
11+
Licenses when the conditions for such availability set forth in the
12+
Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
13+
version 2 with the GNU Classpath Exception, which is available at
14+
https://www.gnu.org/software/classpath/license.html.
15+
16+
SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
17+
18+
-->
19+
20+
<project xmlns="http://maven.apache.org/POM/4.0.0"
21+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
22+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
23+
<parent>
24+
<artifactId>project</artifactId>
25+
<groupId>org.glassfish.jersey.tests.integration</groupId>
26+
<version>2.47-SNAPSHOT</version>
27+
</parent>
28+
<modelVersion>4.0.0</modelVersion>
29+
30+
<artifactId>jersey-5796</artifactId>
31+
<name>jersey-tests-integration-jersey-5796</name>
32+
33+
<dependencies>
34+
<dependency>
35+
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
36+
<artifactId>jersey-test-framework-provider-bundle</artifactId>
37+
<type>pom</type>
38+
<scope>test</scope>
39+
</dependency>
40+
</dependencies>
41+
<build>
42+
<plugins>
43+
<plugin>
44+
<groupId>org.apache.maven.plugins</groupId>
45+
<artifactId>maven-surefire-plugin</artifactId>
46+
<configuration>
47+
<argLine>-XX:+UseG1GC</argLine>
48+
</configuration>
49+
</plugin>
50+
</plugins>
51+
</build>
52+
</project>
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
* Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.tests.integration.jersey5796;
18+
19+
import static org.junit.jupiter.api.Assertions.assertEquals;
20+
21+
import java.io.ByteArrayInputStream;
22+
import java.io.InputStream;
23+
import java.lang.ref.WeakReference;
24+
import java.lang.reflect.Field;
25+
import java.util.Map;
26+
import java.util.concurrent.LinkedBlockingDeque;
27+
import java.util.concurrent.atomic.AtomicInteger;
28+
29+
import javax.ws.rs.GET;
30+
import javax.ws.rs.Path;
31+
import javax.ws.rs.client.Client;
32+
import javax.ws.rs.client.ClientBuilder;
33+
import javax.ws.rs.core.Application;
34+
import javax.ws.rs.core.GenericType;
35+
import javax.ws.rs.core.Response;
36+
37+
import org.glassfish.jersey.client.ChunkedInput;
38+
import org.glassfish.jersey.client.ClientConfig;
39+
import org.glassfish.jersey.client.ClientLifecycleListener;
40+
import org.glassfish.jersey.client.JerseyClient;
41+
import org.glassfish.jersey.server.ChunkedOutput;
42+
import org.glassfish.jersey.server.ResourceConfig;
43+
import org.glassfish.jersey.test.JerseyTest;
44+
import org.junit.jupiter.api.Test;
45+
46+
47+
public class Jersey5796Test extends JerseyTest {
48+
49+
private static final int COUNT = 50;
50+
51+
@Override
52+
protected Application configure() {
53+
return new ResourceConfig(Resource.class);
54+
}
55+
56+
@Test
57+
public void testMemoryLeak() throws Exception {
58+
ClientRuntimeCloseVerifier.closedClientRuntime = new AtomicInteger(0);
59+
Client client = ClientBuilder.newClient(new ClientConfig(ClientRuntimeCloseVerifier.class));
60+
assertEquals(0, ClientRuntimeCloseVerifier.closedClientRuntime.get());
61+
for (int i = 0; i < COUNT; i++) {
62+
Response response = client.target(getBaseUri()).property("test", "test").path("/get1").request().get();
63+
assertEquals("GET", response.readEntity(String.class));
64+
response.close();
65+
}
66+
System.gc();
67+
do {
68+
Thread.sleep(100L);
69+
} while (ClientRuntimeCloseVerifier.closedClientRuntime.get() != 50);
70+
assertEquals(COUNT, ClientRuntimeCloseVerifier.closedClientRuntime.get());
71+
client.close();
72+
73+
}
74+
75+
/* Reproduces issue 4507
76+
MultiException stack 1 of 1
77+
java.lang.IllegalStateException: ServiceLocatorImpl(__HK2_Generated_0,0,427183206) has been shut down
78+
at org.jvnet.hk2.internal.ServiceLocatorImpl.checkState(ServiceLocatorImpl.java:2399)
79+
at org.jvnet.hk2.internal.ServiceLocatorImpl.getServiceHandleImpl(ServiceLocatorImpl.java:627)
80+
at org.jvnet.hk2.internal.ServiceLocatorImpl.getServiceHandle(ServiceLocatorImpl.java:620)
81+
at org.jvnet.hk2.internal.ServiceLocatorImpl.getServiceHandle(ServiceLocatorImpl.java:638)
82+
at org.jvnet.hk2.internal.FactoryCreator.getFactoryHandle(FactoryCreator.java:79)
83+
at org.jvnet.hk2.internal.FactoryCreator.dispose(FactoryCreator.java:149)
84+
at org.jvnet.hk2.internal.SystemDescriptor.dispose(SystemDescriptor.java:521)
85+
at org.glassfish.jersey.inject.hk2.RequestContext.lambda$findOrCreate$0(RequestContext.java:60)
86+
at org.glassfish.jersey.internal.inject.ForeignDescriptorImpl.dispose(ForeignDescriptorImpl.java:63)
87+
at org.glassfish.jersey.inject.hk2.Hk2RequestScope$Instance.remove(Hk2RequestScope.java:126)
88+
at java.base/java.lang.Iterable.forEach(Iterable.java:75)
89+
at org.glassfish.jersey.inject.hk2.Hk2RequestScope$Instance.release(Hk2RequestScope.java:143)
90+
at org.glassfish.jersey.server.ChunkedOutput.flushQueue(ChunkedOutput.java:405)
91+
at org.glassfish.jersey.server.ChunkedOutput.write(ChunkedOutput.java:264)
92+
at org.glassfish.jersey.tests.integration.jersey5796.Jersey5796Test$Resource.lambda$get2$0(Jersey5796Test.java:116)
93+
at java.base/java.lang.Thread.run(Thread.java:1583)
94+
95+
*/
96+
@Test
97+
public void testChunkedInput() throws Exception {
98+
ClientRuntimeCloseVerifier.closedClientRuntime = new AtomicInteger(0);
99+
Client client = ClientBuilder.newClient(new ClientConfig(ClientRuntimeCloseVerifier.class));
100+
assertEquals(0, ClientRuntimeCloseVerifier.closedClientRuntime.get());
101+
for (int i = 0; i < COUNT; i++) {
102+
ChunkedInput<String> chunkedInput = client.target(getBaseUri()).property("test", "test")
103+
.path("/get2").request().get(new GenericType<ChunkedInput<String>>() {});
104+
chunkedInput.setParser(ChunkedInput.createParser("\n"));
105+
int j = 0;
106+
String chunk;
107+
while ((chunk = chunkedInput.read()) != null) {
108+
assertEquals("Chunk " + j, chunk);
109+
j++;
110+
}
111+
chunkedInput.close();
112+
}
113+
System.gc();
114+
do {
115+
Thread.sleep(100L);
116+
} while (ClientRuntimeCloseVerifier.closedClientRuntime.get() != 50);
117+
assertEquals(COUNT, ClientRuntimeCloseVerifier.closedClientRuntime.get());
118+
client.close();
119+
}
120+
121+
@Path("/")
122+
public static class Resource {
123+
124+
@GET
125+
@Path("/get1")
126+
public String get1() {
127+
return "GET";
128+
}
129+
130+
@GET
131+
@Path("/get2")
132+
public ChunkedOutput<String> get2() {
133+
ChunkedOutput<String> output = new ChunkedOutput<>(String.class);
134+
new Thread(() -> {
135+
try {
136+
for (int i = 0; i < 3; i++) {
137+
output.write("Chunk " + i + "\n");
138+
}
139+
} catch (Exception e1) {
140+
e1.printStackTrace();
141+
} finally {
142+
try {
143+
output.close();
144+
} catch (Exception e2) {
145+
e2.printStackTrace();
146+
}
147+
}
148+
}).start();
149+
return output;
150+
}
151+
}
152+
153+
public static class ClientRuntimeCloseVerifier implements ClientLifecycleListener {
154+
155+
private static AtomicInteger closedClientRuntime;
156+
157+
@Override
158+
public void onInit() {
159+
}
160+
161+
@Override
162+
public void onClose() {
163+
closedClientRuntime.incrementAndGet();
164+
}
165+
}
166+
}

tests/integration/pom.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
4-
Copyright (c) 2011, 2024 Oracle and/or its affiliates. All rights reserved.
4+
Copyright (c) 2011, 2025 Oracle and/or its affiliates. All rights reserved.
55
Copyright (c) 2018 Payara Foundation and/or its affiliates. All rights reserved.
66
77
This program and the accompanying materials are made available under the
@@ -93,6 +93,7 @@
9393
<module>jersey-4697</module>
9494
<module>jersey-4722</module>
9595
<module>jersey-4949</module>
96+
<module>jersey-5796</module>
9697
<module>jetty-response-close</module>
9798
<module>microprofile</module>
9899
<module>portability-jersey-1</module>

0 commit comments

Comments
 (0)