Overview ======== - DatagramSocket and MulticastSocket are changed to delegate to either the socket adaptor or the old implementation. The old implemenetation is used when the static factory is configured, jdk.net.usePlainDatagramSocketImpl is set (or set or true), or when DatagramSocket is extended and its protected constructor is used to create a DatagramSocket with a custom impl. - The legacy/old implementation of DatagramSocket and MulticastSocket are copied to DatagramSocketImplWrapper. It is non-public and overrides every public method defined by both DatagramSocket and MulticastSocket. The implementation delegates to the DatagramSocketImpl (either PlainDatagramSocketImpl or custom) as before. Behavior differences ==================== - The main behavior difference between the old and "new" implementation is with connected datagrams. Connected datagrams are emulated on macOS in the old implemenetation. The old implementation also falls back to emulation on other platforms when the connect fails (e.g. connect to a non-routable address). DatagramChannel discards all datagrams in the socket read buffer when connecting the socket whereas the old DatagramSocket implementation will buffer and filter so that datagrams are not discarded. - If DatagramSocket or MulticastSocket is extended and the setReuseAddress, bind, or close methods are overridden, then these methods are not invoked at construction time (the constructor doesn't leak "this"). The old implementation calls the overridden methods at construction time. - The ordering that parameters are checked, the security manager check, and the check for a closed socket may differ so the exception thrown when there are two or more exception conditions may differ.