--- old/src/java.base/share/classes/java/net/DatagramSocket.java 2020-02-14 09:51:54.000000000 +0000 +++ new/src/java.base/share/classes/java/net/DatagramSocket.java 2020-02-14 09:51:54.000000000 +0000 @@ -25,6 +25,7 @@ package java.net; +import java.io.FileDescriptor; import java.io.IOException; import java.io.UncheckedIOException; import java.nio.channels.DatagramChannel; @@ -124,6 +125,7 @@ /* * The implementation of this DatagramSocket. */ + @SuppressWarnings("deprecation") private final DatagramSocketImpl impl; /** @@ -252,7 +254,7 @@ * the subclass wishes to use on the DatagramSocket. * @since 1.4 */ - protected DatagramSocket(DatagramSocketImpl impl) { + protected DatagramSocket(@SuppressWarnings("deprecation")DatagramSocketImpl impl) { if (impl == null) throw new NullPointerException(); this.impl = impl; @@ -283,13 +285,6 @@ * @since 1.4 */ public DatagramSocket(SocketAddress bindaddr) throws SocketException { - // Special case initialization for the DatagramChannel socket adaptor. - if (this instanceof sun.nio.ch.DatagramSocketAdaptor) { - this.impl = null; // no DatagramSocketImpl - this.oldImpl = false; - return; - } - // create a datagram socket. boolean multicast = (this instanceof MulticastSocket); this.impl = createImpl(multicast); @@ -363,7 +358,7 @@ * Return true if the given DatagramSocketImpl is an "old" impl. An old impl * is one that doesn't implement the abstract methods added in Java SE 1.4. */ - private static boolean checkOldImpl(DatagramSocketImpl impl) { + private static boolean checkOldImpl(@SuppressWarnings("deprecation")DatagramSocketImpl impl) { // DatagramSocketImpl.peekData() is a protected method, therefore we need to use // getDeclaredMethod, therefore we need permission to access the member try { @@ -388,6 +383,7 @@ * Creates a DatagramSocketImpl. * @param multicast true if the DatagramSocketImpl is for a MulticastSocket */ + @SuppressWarnings("deprecation") private static DatagramSocketImpl createImpl(boolean multicast) throws SocketException { DatagramSocketImpl impl; DatagramSocketImplFactory factory = DatagramSocket.factory; @@ -408,7 +404,7 @@ * @throws SocketException if creating the socket fails * @since 1.4 */ - final DatagramSocketImpl getImpl() throws SocketException { + final @SuppressWarnings("deprecation")DatagramSocketImpl getImpl() throws SocketException { if (!created) { synchronized (this) { if (!created) { @@ -1503,7 +1499,7 @@ return options; } try { - DatagramSocketImpl impl = getImpl(); + @SuppressWarnings("deprecation")DatagramSocketImpl impl = getImpl(); options = Collections.unmodifiableSet(impl.supportedOptions()); } catch (IOException e) { options = Collections.emptySet(); @@ -1512,4 +1508,57 @@ return options; } } + + /** + * An instance of a {@code DatagramSocketImpl} whose methods all throw an + * {@UncheckedIOException}. + * + *
Suitable for use by subclasses of {@code DatagramSocket} and + * {@code MulticastSocket}, that wish to provide their own complete + * implementation, without delegating to the enclosing {@code impl} class. + * For example: + * + *
{@code + * class CustomDatagramSocket extends DatagramSocket { + * CustomDatagramSocket() { + * super(DatagramSocket.THROWING_DGRM_IMPL); + * } + * + * // override of all methods of DatagramSocket ... + * } + * }+ */ + // TODO: find a better name + @SuppressWarnings("deprecation") + protected static final DatagramSocketImpl THROWING_DGRM_IMPL = new DatagramSocketImpl() { + private final void throwUncheckedIOException() { + throw new UncheckedIOException(new IOException("unimplemented")); + } + @Override protected void create() { throwUncheckedIOException(); } + @Override protected void bind(int p, InetAddress a) { throwUncheckedIOException(); } + @Override protected void send(DatagramPacket p) { throwUncheckedIOException(); } + @Override protected void connect(InetAddress a, int p) { throwUncheckedIOException(); } + @Override protected void disconnect() { throwUncheckedIOException(); } + @Override protected int getLocalPort() { throwUncheckedIOException(); return 0; } + @Override protected FileDescriptor getFileDescriptor() { throwUncheckedIOException(); return null; } + @Override protected int peek(InetAddress i) { throwUncheckedIOException(); return 0; } + @Override protected int peekData(DatagramPacket p) { throwUncheckedIOException(); return 0; } + @Override protected void receive(DatagramPacket p) { throwUncheckedIOException(); } + @Override protected void setTTL(byte ttl) { throwUncheckedIOException(); } + @Override protected byte getTTL() { throwUncheckedIOException(); return 0; } + @Override protected void setTimeToLive(int ttl) { throwUncheckedIOException(); } + @Override protected int getTimeToLive() { throwUncheckedIOException(); return 0; } + @Override protected void join(InetAddress a) { throwUncheckedIOException(); } + @Override protected void leave(InetAddress a) { throwUncheckedIOException(); } + @Override protected void joinGroup(SocketAddress a, + NetworkInterface b) { throwUncheckedIOException(); } + @Override protected void leaveGroup(SocketAddress a, + NetworkInterface b) { throwUncheckedIOException(); } + @Override protected void close() { throwUncheckedIOException(); } + @Override public void setOption(int o, Object v) { throwUncheckedIOException(); } + @Override public Object getOption(int o) { throwUncheckedIOException(); return null; } + @Override protected
DatagramSocketImpl
.
*/
+ @SuppressWarnings("deprecation")
static DatagramSocketImpl createDatagramSocketImpl(boolean isMulticast /*unused on unix*/)
throws SocketException {
if (prefixImplClass != null) {
try {
- @SuppressWarnings("deprecation")
DatagramSocketImpl result = (DatagramSocketImpl)prefixImplClass.newInstance();
return result;
} catch (Exception e) {
--- /dev/null 2020-02-14 09:52:19.000000000 +0000
+++ new/test/jdk/java/net/DatagramSocketImpl/NoWarningSubclasses.java 2020-02-14 09:52:18.000000000 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1998, 2019, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8765432
+ * @summary Ensures that there is a warning-free way to compile subclasses
+ * of DatagramSocket and MulticastSocket
+ * @compile -Xlint:all -Werror NoWarningSubclasses.java
+ */
+
+import java.net.DatagramSocket;
+import java.net.MulticastSocket;
+
+public class NoWarningSubclasses {
+
+ static class TestDatagramSocket extends DatagramSocket {
+ TestDatagramSocket() {
+ super(DatagramSocket.THROWING_DGRM_IMPL);
+ }
+ }
+
+ static class TestMulticastSocket extends MulticastSocket {
+ TestMulticastSocket() {
+ super(DatagramSocket.THROWING_DGRM_IMPL);
+ }
+ }
+}