mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 18:44:38 +02:00
8241072: Reimplement the Legacy DatagramSocket API
Replace the underlying implementations of the java.net.DatagramSocket and java.net.MulticastSocket APIs with simpler and more modern implementations that are easy to maintain and debug. Co-authored-by: Alan Bateman <alan.bateman@oracle.com> Co-authored-by: Chris Hegarty <chris.hegarty@oracle.com> Co-authored-by: Daniel Fuchs <daniel.fuchs@oracle.com> Reviewed-by: alanb, chegar, dfuchs
This commit is contained in:
parent
3930460af5
commit
fad2cf51ba
34 changed files with 1478 additions and 909 deletions
|
@ -25,6 +25,8 @@
|
|||
* @test
|
||||
* @bug 6427403
|
||||
* @summary java.net.MulticastSocket.joinGroup() reports 'socket closed'
|
||||
* @run main B6427403
|
||||
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl B6427403
|
||||
*/
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
* @library /test/lib
|
||||
* @summary Test that MutlicastSocket.joinGroup is working for
|
||||
* various multicast and non-multicast addresses.
|
||||
* @run main MulticastAddresses
|
||||
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl MulticastAddresses
|
||||
*/
|
||||
|
||||
import jdk.test.lib.NetworkConfiguration;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* @run main/othervm NoSetNetworkInterface
|
||||
* @run main/othervm -Djava.net.preferIPv4Stack=true NoSetNetworkInterface
|
||||
* @run main/othervm -Djava.net.preferIPv6Addresses=true NoSetNetworkInterface
|
||||
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl NoSetNetworkInterface
|
||||
* @summary Check that methods that are used to set and get the NetworkInterface
|
||||
* for a MulticastSocket work as expected. This test also checks that getOption
|
||||
* returns null correctly when a NetworkInterface has not been set
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
* @library /test/lib
|
||||
* @summary Test for interference when two sockets are bound to the same
|
||||
* port but joined to different multicast groups
|
||||
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl Promiscuous
|
||||
* @run main Promiscuous
|
||||
* @run main/othervm -Djava.net.preferIPv4Stack=true Promiscuous
|
||||
*/
|
||||
|
|
|
@ -48,7 +48,8 @@ import static org.testng.Assert.assertThrows;
|
|||
* @bug 8243408
|
||||
* @summary Check that MulticastSocket throws expected
|
||||
* Exception when sending a DatagramPacket with port 0
|
||||
* @run testng/othervm SendPortZero
|
||||
* @run testng SendPortZero
|
||||
* @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl SendPortZero
|
||||
*/
|
||||
|
||||
public class SendPortZero {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* @build jdk.test.lib.NetworkConfiguration
|
||||
* jdk.test.lib.Platform
|
||||
* @run main/othervm SetLoopbackMode
|
||||
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl SetLoopbackMode
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
@ -53,6 +54,8 @@ public class SetLoopbackMode {
|
|||
System.out.println("Loopback mode is enabled.");
|
||||
}
|
||||
|
||||
System.out.println(mc.getLocalSocketAddress());
|
||||
|
||||
byte b[] = "hello".getBytes();
|
||||
DatagramPacket p = new DatagramPacket(b, b.length, grp,
|
||||
mc.getLocalPort());
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
* SetLoopbackMode
|
||||
* SetLoopbackModeIPv4
|
||||
* @run main/othervm -Djava.net.preferIPv4Stack=true SetLoopbackModeIPv4
|
||||
* @run main/othervm -Djava.net.preferIPv4Stack=true
|
||||
* -Djdk.net.usePlainDatagramSocketImpl SetLoopbackModeIPv4
|
||||
*/
|
||||
|
||||
import jdk.test.lib.net.IPSupport;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
* @run testng/othervm SetLoopbackOption
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack=true SetLoopbackOption
|
||||
* @run testng/othervm -Djava.net.preferIPv6Addresses=true SetLoopbackOption
|
||||
* @run testng/othervm -Djdk.net.usePlainDatagramSocketImpl SetLoopbackOption
|
||||
*/
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
* @bug 4742177 8241786
|
||||
* @library /test/lib
|
||||
* @run main/othervm SetOutgoingIf
|
||||
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl SetOutgoingIf
|
||||
* @summary Re-test IPv6 (and specifically MulticastSocket) with latest Linux & USAGI code
|
||||
*/
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
/* @test
|
||||
* @bug 4189640
|
||||
* @summary Make setTTL/getTTL works
|
||||
* @run main SetTTLAndGetTTL
|
||||
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl SetTTLAndGetTTL
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
/* @test
|
||||
* @bug 4148757
|
||||
* @summary Make sure TTL can be set to 0
|
||||
* @run main SetTTLTo0
|
||||
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl SetTTLTo0
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 2020, 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
|
||||
|
@ -25,7 +25,9 @@
|
|||
* @test
|
||||
* @library /test/lib
|
||||
* @modules java.management java.base/java.io:+open java.base/java.net:+open
|
||||
* java.base/sun.net
|
||||
* @run main/othervm -Djava.net.preferIPv4Stack=true UnreferencedMulticastSockets
|
||||
* @run main/othervm -Djdk.net.usePlainDatagramSocketImpl UnreferencedMulticastSockets
|
||||
* @run main/othervm UnreferencedMulticastSockets
|
||||
* @summary Check that unreferenced multicast sockets are closed
|
||||
*/
|
||||
|
@ -37,6 +39,7 @@ import java.lang.ref.ReferenceQueue;
|
|||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Field;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.DatagramSocketImpl;
|
||||
|
@ -44,9 +47,12 @@ import java.net.InetAddress;
|
|||
import java.net.InetSocketAddress;
|
||||
import java.net.MulticastSocket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.channels.DatagramChannel;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
@ -56,6 +62,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import jdk.test.lib.net.IPSupport;
|
||||
|
||||
import com.sun.management.UnixOperatingSystemMXBean;
|
||||
import sun.net.NetProperties;
|
||||
|
||||
public class UnreferencedMulticastSockets {
|
||||
|
||||
|
@ -223,32 +230,62 @@ public class UnreferencedMulticastSockets {
|
|||
: -1L;
|
||||
}
|
||||
|
||||
// Reflect to find references in the socket implementation that will be gc'd
|
||||
private static void extractRefs(MulticastSocket s, String name) {
|
||||
private static boolean usePlainDatagramSocketImpl() {
|
||||
PrivilegedAction<String> pa = () -> NetProperties.get("jdk.net.usePlainDatagramSocketImpl");
|
||||
String s = AccessController.doPrivileged(pa);
|
||||
return (s != null) && (s.isEmpty() || s.equalsIgnoreCase("true"));
|
||||
}
|
||||
|
||||
// Reflect to find references in the datagram implementation that will be gc'd
|
||||
private static void extractRefs(DatagramSocket s, String name) {
|
||||
|
||||
try {
|
||||
Field datagramSocketField = DatagramSocket.class.getDeclaredField("delegate");
|
||||
datagramSocketField.setAccessible(true);
|
||||
|
||||
Field socketImplField = DatagramSocket.class.getDeclaredField("impl");
|
||||
socketImplField.setAccessible(true);
|
||||
Object socketImpl = socketImplField.get(s);
|
||||
if (!usePlainDatagramSocketImpl()) {
|
||||
// MulticastSocket using DatagramSocketAdaptor
|
||||
Object MulticastSocket = datagramSocketField.get(s);
|
||||
|
||||
Field fileDescriptorField = DatagramSocketImpl.class.getDeclaredField("fd");
|
||||
fileDescriptorField.setAccessible(true);
|
||||
FileDescriptor fileDescriptor = (FileDescriptor) fileDescriptorField.get(socketImpl);
|
||||
extractRefs(fileDescriptor, name);
|
||||
Method m = DatagramSocket.class.getDeclaredMethod("getChannel");
|
||||
m.setAccessible(true);
|
||||
DatagramChannel datagramChannel = (DatagramChannel) m.invoke(MulticastSocket);
|
||||
|
||||
Class<?> socketImplClass = socketImpl.getClass();
|
||||
System.out.printf("socketImplClass: %s%n", socketImplClass);
|
||||
if (socketImplClass.getName().equals("java.net.TwoStacksPlainDatagramSocketImpl")) {
|
||||
Field fileDescriptor1Field = socketImplClass.getDeclaredField("fd1");
|
||||
fileDescriptor1Field.setAccessible(true);
|
||||
FileDescriptor fileDescriptor1 = (FileDescriptor) fileDescriptor1Field.get(socketImpl);
|
||||
extractRefs(fileDescriptor1, name + "::twoStacksFd1");
|
||||
assert datagramChannel.getClass() == Class.forName("sun.nio.ch.DatagramChannelImpl");
|
||||
|
||||
Field fileDescriptorField = datagramChannel.getClass().getDeclaredField("fd");
|
||||
fileDescriptorField.setAccessible(true);
|
||||
FileDescriptor fileDescriptor = (FileDescriptor) fileDescriptorField.get(datagramChannel);
|
||||
extractRefs(fileDescriptor, name);
|
||||
|
||||
} else {
|
||||
System.out.printf("socketImpl class name not matched: %s != %s%n",
|
||||
socketImplClass.getName(), "java.net.TwoStacksPlainDatagramSocketImpl");
|
||||
// MulticastSocket using PlainDatagramSocketImpl
|
||||
Object MulticastSocket = datagramSocketField.get(s);
|
||||
assert MulticastSocket.getClass() == Class.forName("java.net.NetMulticastSocket");
|
||||
|
||||
Method m = MulticastSocket.getClass().getDeclaredMethod("getImpl");
|
||||
m.setAccessible(true);
|
||||
DatagramSocketImpl datagramSocketImpl = (DatagramSocketImpl) m.invoke(MulticastSocket);
|
||||
|
||||
Field fileDescriptorField = DatagramSocketImpl.class.getDeclaredField("fd");
|
||||
fileDescriptorField.setAccessible(true);
|
||||
FileDescriptor fileDescriptor = (FileDescriptor) fileDescriptorField.get(datagramSocketImpl);
|
||||
extractRefs(fileDescriptor, name);
|
||||
|
||||
Class<?> socketImplClass = datagramSocketImpl.getClass();
|
||||
System.out.printf("socketImplClass: %s%n", socketImplClass);
|
||||
if (socketImplClass.getName().equals("java.net.TwoStacksPlainDatagramSocketImpl")) {
|
||||
Field fileDescriptor1Field = socketImplClass.getDeclaredField("fd1");
|
||||
fileDescriptor1Field.setAccessible(true);
|
||||
FileDescriptor fileDescriptor1 = (FileDescriptor) fileDescriptor1Field.get(datagramSocketImpl);
|
||||
extractRefs(fileDescriptor1, name + "::twoStacksFd1");
|
||||
|
||||
} else {
|
||||
System.out.printf("socketImpl class name not matched: %s != %s%n",
|
||||
socketImplClass.getName(), "java.net.TwoStacksPlainDatagramSocketImpl");
|
||||
}
|
||||
}
|
||||
} catch (NoSuchFieldException | IllegalAccessException ex) {
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
throw new AssertionError("missing field", ex);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue