8330814: Cleanups for KeepAliveCache tests
Reviewed-by: jpai, dfuchs
This commit is contained in:
parent
1a944478a2
commit
a5005c87c4
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,9 +24,9 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 5045306 6356004 6993490 8255124
|
||||
* @summary Http keep-alive implementation is not efficient
|
||||
* @library /test/lib
|
||||
* @run main/othervm B5045306
|
||||
* @summary Http keep-alive implementation is not efficient
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
@ -42,14 +42,17 @@ import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
|
||||
import jdk.test.lib.net.URIBuilder;
|
||||
|
||||
/* Part 1:
|
||||
* The http client makes a connection to a URL whos content contains a lot of
|
||||
* The http client makes a connection to a URL whose content contains a lot of
|
||||
* data, more than can fit in the socket buffer. The client only reads
|
||||
* 1 byte of the data from the InputStream leaving behind more data than can
|
||||
* fit in the socket buffer. The client then makes a second call to the http
|
||||
@ -63,150 +66,166 @@ import com.sun.net.httpserver.HttpServer;
|
||||
|
||||
public class B5045306 {
|
||||
static HttpServer server;
|
||||
|
||||
public static void main(String[] args) {
|
||||
startHttpServer();
|
||||
clientHttpCalls();
|
||||
}
|
||||
static ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
|
||||
public static void startHttpServer() {
|
||||
try {
|
||||
server = HttpServer.create(new InetSocketAddress(InetAddress.getLocalHost(), 0), 10, "/", new SimpleHttpTransactionHandler());
|
||||
server.setExecutor(Executors.newSingleThreadExecutor());
|
||||
server.start();
|
||||
server = HttpServer.create(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 10, "/", new SimpleHttpTransactionHandler());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
server.setExecutor(executor);
|
||||
server.start();
|
||||
System.out.println("http server listens on: " + server.getAddress());
|
||||
}
|
||||
|
||||
public static void clientHttpCalls() {
|
||||
public static void stopHttpServer() {
|
||||
server.stop(1);
|
||||
executor.shutdown();
|
||||
}
|
||||
|
||||
public static void clientHttpCalls() throws Exception {
|
||||
List<Throwable> uncaught = new ArrayList<>();
|
||||
Thread.setDefaultUncaughtExceptionHandler((t, ex) -> {
|
||||
uncaught.add(ex);
|
||||
});
|
||||
try {
|
||||
System.out.println("http server listen on: " + server.getAddress().getPort());
|
||||
String hostAddr = InetAddress.getLocalHost().getHostAddress();
|
||||
if (hostAddr.indexOf(':') > -1) hostAddr = "[" + hostAddr + "]";
|
||||
String baseURLStr = "http://" + hostAddr + ":" + server.getAddress().getPort() + "/";
|
||||
|
||||
URL bigDataURL = new URL (baseURLStr + "firstCall");
|
||||
URL smallDataURL = new URL (baseURLStr + "secondCall");
|
||||
URL bigDataURL = URIBuilder.newBuilder()
|
||||
.scheme("http")
|
||||
.loopback()
|
||||
.port(server.getAddress().getPort())
|
||||
.path("/firstCall")
|
||||
.toURL();
|
||||
|
||||
HttpURLConnection uc = (HttpURLConnection)bigDataURL.openConnection(Proxy.NO_PROXY);
|
||||
URL smallDataURL = URIBuilder.newBuilder()
|
||||
.scheme("http")
|
||||
.loopback()
|
||||
.port(server.getAddress().getPort())
|
||||
.path("/secondCall")
|
||||
.toURL();
|
||||
|
||||
//Only read 1 byte of response data and close the stream
|
||||
InputStream is = uc.getInputStream();
|
||||
HttpURLConnection uc = (HttpURLConnection)bigDataURL.openConnection(Proxy.NO_PROXY);
|
||||
|
||||
// Only read 1 byte of response data and close the stream
|
||||
try (InputStream is = uc.getInputStream()) {
|
||||
byte[] ba = new byte[1];
|
||||
is.read(ba);
|
||||
is.close();
|
||||
}
|
||||
|
||||
// Allow the KeepAliveStreamCleaner thread to read the data left behind and cache the connection.
|
||||
try { Thread.sleep(2000); } catch (Exception e) {}
|
||||
// Allow the KeepAliveStreamCleaner thread to read the data left behind and cache the connection.
|
||||
try { Thread.sleep(2000); } catch (Exception e) {}
|
||||
|
||||
uc = (HttpURLConnection)smallDataURL.openConnection(Proxy.NO_PROXY);
|
||||
uc.getResponseCode();
|
||||
uc = (HttpURLConnection)smallDataURL.openConnection(Proxy.NO_PROXY);
|
||||
uc.getResponseCode();
|
||||
|
||||
if (SimpleHttpTransactionHandler.failed)
|
||||
throw new RuntimeException("Failed: Initial Keep Alive Connection is not being reused");
|
||||
if (SimpleHttpTransactionHandler.failed)
|
||||
throw new RuntimeException("Failed: Initial Keep Alive Connection is not being reused");
|
||||
|
||||
// Part 2
|
||||
URL part2Url = new URL (baseURLStr + "part2");
|
||||
uc = (HttpURLConnection)part2Url.openConnection(Proxy.NO_PROXY);
|
||||
is = uc.getInputStream();
|
||||
is.close();
|
||||
// Part 2
|
||||
URL part2Url = URIBuilder.newBuilder()
|
||||
.scheme("http")
|
||||
.loopback()
|
||||
.port(server.getAddress().getPort())
|
||||
.path("/part2")
|
||||
.toURL();
|
||||
|
||||
// Allow the KeepAliveStreamCleaner thread to try and read the data left behind and cache the connection.
|
||||
try { Thread.sleep(2000); } catch (Exception e) {}
|
||||
uc = (HttpURLConnection)part2Url.openConnection(Proxy.NO_PROXY);
|
||||
try (InputStream is = uc.getInputStream()) {}
|
||||
|
||||
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
|
||||
if (threadMXBean.isThreadCpuTimeSupported()) {
|
||||
long[] threads = threadMXBean.getAllThreadIds();
|
||||
ThreadInfo[] threadInfo = threadMXBean.getThreadInfo(threads);
|
||||
for (int i=0; i<threadInfo.length; i++) {
|
||||
if (threadInfo[i].getThreadName().equals("Keep-Alive-SocketCleaner")) {
|
||||
System.out.println("Found Keep-Alive-SocketCleaner thread");
|
||||
long threadID = threadInfo[i].getThreadId();
|
||||
long before = threadMXBean.getThreadCpuTime(threadID);
|
||||
try { Thread.sleep(2000); } catch (Exception e) {}
|
||||
long after = threadMXBean.getThreadCpuTime(threadID);
|
||||
// Allow the KeepAliveStreamCleaner thread to try and read the data left behind and cache the connection.
|
||||
try { Thread.sleep(2000); } catch (Exception e) {}
|
||||
|
||||
if (before ==-1 || after == -1)
|
||||
break; // thread has died, OK
|
||||
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
|
||||
if (threadMXBean.isThreadCpuTimeSupported()) {
|
||||
long[] threads = threadMXBean.getAllThreadIds();
|
||||
ThreadInfo[] threadInfo = threadMXBean.getThreadInfo(threads);
|
||||
for (int i = 0; i < threadInfo.length; i++) {
|
||||
if (threadInfo[i].getThreadName().equals("Keep-Alive-SocketCleaner")) {
|
||||
System.out.println("Found Keep-Alive-SocketCleaner thread");
|
||||
long threadID = threadInfo[i].getThreadId();
|
||||
long before = threadMXBean.getThreadCpuTime(threadID);
|
||||
try { Thread.sleep(2000); } catch (Exception e) {}
|
||||
long after = threadMXBean.getThreadCpuTime(threadID);
|
||||
|
||||
// if Keep-Alive-SocketCleaner consumes more than 50% of cpu then we
|
||||
// can assume a recursive loop.
|
||||
long total = after - before;
|
||||
if (total >= 1000000000) // 1 second, or 1 billion nanoseconds
|
||||
throw new RuntimeException("Failed: possible recursive loop in Keep-Alive-SocketCleaner");
|
||||
}
|
||||
if (before ==-1 || after == -1)
|
||||
break; // thread has died, OK
|
||||
|
||||
// if Keep-Alive-SocketCleaner consumes more than 50% of cpu then we
|
||||
// can assume a recursive loop.
|
||||
long total = after - before;
|
||||
if (total >= 1000000000) // 1 second, or 1 billion nanoseconds
|
||||
throw new RuntimeException("Failed: possible recursive loop in Keep-Alive-SocketCleaner");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
server.stop(1);
|
||||
}
|
||||
if (!uncaught.isEmpty()) {
|
||||
throw new RuntimeException("Unhandled exception:", uncaught.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SimpleHttpTransactionHandler implements HttpHandler
|
||||
{
|
||||
static volatile boolean failed = false;
|
||||
static class SimpleHttpTransactionHandler implements HttpHandler {
|
||||
static volatile boolean failed = false;
|
||||
|
||||
// Need to have enough data here that is too large for the socket buffer to hold.
|
||||
// Also http.KeepAlive.remainingData must be greater than this value, default is 256K.
|
||||
static final int RESPONSE_DATA_LENGTH = 128 * 1024;
|
||||
// Need to have enough data here that is too large for the socket buffer to hold.
|
||||
// Also http.KeepAlive.remainingData must be greater than this value, default is 256K.
|
||||
static final int RESPONSE_DATA_LENGTH = 128 * 1024;
|
||||
|
||||
int port1;
|
||||
int port1;
|
||||
|
||||
public void handle(HttpExchange trans) {
|
||||
try {
|
||||
String path = trans.getRequestURI().getPath();
|
||||
if (path.equals("/firstCall")) {
|
||||
port1 = trans.getRemoteAddress().getPort();
|
||||
System.out.println("First connection on client port = " + port1);
|
||||
public void handle(HttpExchange trans) {
|
||||
try {
|
||||
String path = trans.getRequestURI().getPath();
|
||||
if (path.equals("/firstCall")) {
|
||||
port1 = trans.getRemoteAddress().getPort();
|
||||
System.out.println("First connection on client port = " + port1);
|
||||
|
||||
byte[] responseBody = new byte[RESPONSE_DATA_LENGTH];
|
||||
for (int i=0; i<responseBody.length; i++)
|
||||
responseBody[i] = 0x41;
|
||||
trans.sendResponseHeaders(200, responseBody.length);
|
||||
try (OutputStream os = trans.getResponseBody()) {
|
||||
byte[] responseBody = new byte[RESPONSE_DATA_LENGTH];
|
||||
for (int i=0; i<responseBody.length; i++)
|
||||
responseBody[i] = 0x41;
|
||||
trans.sendResponseHeaders(200, responseBody.length);
|
||||
try (OutputStream os = trans.getResponseBody()) {
|
||||
os.write(responseBody);
|
||||
}
|
||||
} else if (path.equals("/secondCall")) {
|
||||
int port2 = trans.getRemoteAddress().getPort();
|
||||
System.out.println("Second connection on client port = " + port2);
|
||||
|
||||
if (port1 != port2)
|
||||
failed = true;
|
||||
|
||||
/* Force the server to not respond for more that the timeout
|
||||
* set by the keepalive cleaner (5000 millis). This ensures the
|
||||
* timeout is correctly resets the default read timeout,
|
||||
* infinity. See 6993490. */
|
||||
System.out.println("server sleeping...");
|
||||
try {Thread.sleep(6000); } catch (InterruptedException e) {}
|
||||
trans.sendResponseHeaders(200, -1);
|
||||
} else if (path.equals("/part2")) {
|
||||
System.out.println("Call to /part2");
|
||||
byte[] responseBody = new byte[RESPONSE_DATA_LENGTH];
|
||||
for (int i=0; i<responseBody.length; i++)
|
||||
responseBody[i] = 0x41;
|
||||
// override the Content-length header to be greater than the actual response body
|
||||
trans.sendResponseHeaders(200, responseBody.length+1);
|
||||
OutputStream os = trans.getResponseBody();
|
||||
os.write(responseBody);
|
||||
// now close the socket
|
||||
// closing the stream here would throw; close the exchange instead
|
||||
trans.close();
|
||||
}
|
||||
} else if (path.equals("/secondCall")) {
|
||||
int port2 = trans.getRemoteAddress().getPort();
|
||||
System.out.println("Second connection on client port = " + port2);
|
||||
|
||||
if (port1 != port2)
|
||||
failed = true;
|
||||
|
||||
/* Force the server to not respond for more that the timeout
|
||||
* set by the keepalive cleaner (5000 millis). This ensures the
|
||||
* timeout is correctly resets the default read timeout,
|
||||
* infinity. See 6993490. */
|
||||
System.out.println("server sleeping...");
|
||||
try {Thread.sleep(6000); } catch (InterruptedException e) {}
|
||||
trans.sendResponseHeaders(200, -1);
|
||||
} else if(path.equals("/part2")) {
|
||||
System.out.println("Call to /part2");
|
||||
byte[] responseBody = new byte[RESPONSE_DATA_LENGTH];
|
||||
for (int i=0; i<responseBody.length; i++)
|
||||
responseBody[i] = 0x41;
|
||||
// override the Content-length header to be greater than the actual response body
|
||||
trans.sendResponseHeaders(200, responseBody.length+1);
|
||||
OutputStream os = trans.getResponseBody();
|
||||
os.write(responseBody);
|
||||
// now close the socket
|
||||
// closing the stream here would throw; close the exchange instead
|
||||
trans.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
failed = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
startHttpServer();
|
||||
try {
|
||||
clientHttpCalls();
|
||||
} finally {
|
||||
stopHttpServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,43 +24,45 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 8291637
|
||||
* @run main/othervm -Dhttp.keepAlive.time.server=20 -esa -ea B8291637 timeout
|
||||
* @run main/othervm -Dhttp.keepAlive.time.server=20 -esa -ea B8291637 max
|
||||
* @library /test/lib
|
||||
* @run main/othervm -Dhttp.keepAlive.time.server=20 -esa -ea B8291637
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import jdk.test.lib.net.URIBuilder;
|
||||
|
||||
public class B8291637 {
|
||||
static CompletableFuture<Boolean> passed = new CompletableFuture<>();
|
||||
|
||||
static class Server extends Thread {
|
||||
final ServerSocket serverSocket;
|
||||
final int port;
|
||||
static class Server extends Thread implements AutoCloseable {
|
||||
final String param; // the parameter to test "max" or "timeout"
|
||||
final ServerSocket serverSocket = new ServerSocket(0);
|
||||
final int port;
|
||||
volatile Socket s;
|
||||
|
||||
public Server(String param) throws IOException {
|
||||
serverSocket = new ServerSocket(0);
|
||||
this.param = param;
|
||||
port = serverSocket.getLocalPort();
|
||||
setDaemon(true);
|
||||
this.param = param;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
serverSocket.close();
|
||||
if (s != null)
|
||||
s.close();
|
||||
} catch (IOException e) {}
|
||||
public void close() throws IOException {
|
||||
serverSocket.close();
|
||||
if (s != null)
|
||||
s.close();
|
||||
}
|
||||
|
||||
static final byte[] requestEnd = new byte[] {'\r', '\n', '\r', '\n' };
|
||||
@ -125,28 +127,29 @@ public class B8291637 {
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Server server = new Server(args[0]);
|
||||
int port = server.getPort();
|
||||
server.start();
|
||||
URL url = new URL("http://127.0.0.1:" + Integer.toString(port) + "/");
|
||||
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
|
||||
InputStream i = urlc.getInputStream();
|
||||
int c,count=0;
|
||||
byte[] buf = new byte[256];
|
||||
while ((c=i.read(buf)) != -1) {
|
||||
count+=c;
|
||||
}
|
||||
i.close();
|
||||
System.out.println("Read " + count );
|
||||
try {
|
||||
public static void runTest(String param) throws Exception {
|
||||
try (Server server = new Server(param)) {
|
||||
server.start();
|
||||
URL url = URIBuilder.newBuilder()
|
||||
.scheme("http")
|
||||
.loopback()
|
||||
.port(server.getPort())
|
||||
.path("/")
|
||||
.toURL();
|
||||
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
|
||||
try (InputStream i = urlc.getInputStream()) {
|
||||
System.out.println("Read " + i.readAllBytes().length);
|
||||
}
|
||||
if (!passed.get()) {
|
||||
throw new RuntimeException("Test failed");
|
||||
} else {
|
||||
System.out.println("Test passed");
|
||||
}
|
||||
} finally {
|
||||
server.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
runTest("timeout");
|
||||
runTest("max");
|
||||
}
|
||||
}
|
||||
|
@ -24,20 +24,11 @@
|
||||
/*
|
||||
* @test
|
||||
* @bug 8293562
|
||||
* @summary Http keep-alive thread should close sockets without holding a lock
|
||||
* @library /test/lib
|
||||
* @run main/othervm -Dhttp.keepAlive.time.server=1 B8293562
|
||||
* @summary Http keep-alive thread should close sockets without holding a lock
|
||||
*/
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
|
||||
import javax.net.ssl.HandshakeCompletedListener;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -53,6 +44,18 @@ import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.net.ssl.HandshakeCompletedListener;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
|
||||
import jdk.test.lib.net.URIBuilder;
|
||||
|
||||
public class B8293562 {
|
||||
static HttpServer server;
|
||||
static CountDownLatch closing = new CountDownLatch(1);
|
||||
@ -73,12 +76,13 @@ public class B8293562 {
|
||||
|
||||
public static void clientHttpCalls() throws Exception {
|
||||
try {
|
||||
System.out.println("http server listen on: " + server.getAddress().getPort());
|
||||
String hostAddr = InetAddress.getLoopbackAddress().getHostAddress();
|
||||
if (hostAddr.indexOf(':') > -1) hostAddr = "[" + hostAddr + "]";
|
||||
String baseURLStr = "https://" + hostAddr + ":" + server.getAddress().getPort() + "/";
|
||||
System.out.println("http server listens on: " + server.getAddress().getPort());
|
||||
|
||||
URL testUrl = new URL (baseURLStr);
|
||||
URL testUrl = URIBuilder.newBuilder()
|
||||
.scheme("https")
|
||||
.loopback()
|
||||
.port(server.getAddress().getPort())
|
||||
.toURL();
|
||||
|
||||
// SlowCloseSocketFactory is not a real SSLSocketFactory;
|
||||
// it produces regular non-SSL sockets. Effectively, the request
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,18 +23,29 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @library /test/lib
|
||||
* @bug 8278067
|
||||
* @library /test/lib
|
||||
* @run main/othervm -Dhttp.keepAlive.time.server=30 KeepAliveProperty long
|
||||
* @run main/othervm -Dhttp.keepAlive.time.server=1 KeepAliveProperty short
|
||||
* @run main/othervm -ea -Dhttp.keepAlive.time.server=0 KeepAliveProperty short
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.nio.charset.*;
|
||||
import java.util.logging.*;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import jdk.test.lib.net.URIBuilder;
|
||||
|
||||
import static java.net.Proxy.NO_PROXY;
|
||||
|
||||
public class KeepAliveProperty {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,16 +23,26 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @library /test/lib
|
||||
* @bug 4701299
|
||||
* @summary Keep-Alive-Timer thread management in KeepAliveCache causes memory leak
|
||||
* @library /test/lib
|
||||
* @run main KeepAliveTimerThread
|
||||
* @run main/othervm -Djava.net.preferIPv6Addresses=true KeepAliveTimerThread
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
|
||||
import jdk.test.lib.net.URIBuilder;
|
||||
|
||||
import static java.net.Proxy.NO_PROXY;
|
||||
|
||||
public class KeepAliveTimerThread {
|
||||
@ -131,8 +141,5 @@ public class KeepAliveTimerThread {
|
||||
if (grp.activeCount() > 0) {
|
||||
throw new RuntimeException("Keep-alive thread started in wrong thread group");
|
||||
}
|
||||
|
||||
grp.destroy();
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user