diff --git a/doc/release/CHANGES.txt b/doc/release/CHANGES.txt index f8046d17..44f4a7f7 100644 --- a/doc/release/CHANGES.txt +++ b/doc/release/CHANGES.txt @@ -29,6 +29,7 @@ E 456 MimeMessage.setFrom(null) fails instead of removing the header E 461 OAuth2 POP3 Support for Microsoft E 473 Several modules are not included in build when JDK11 is used E 493 javamail.providers file missing from provider jars after 1.6.5 +E 505 WriteTimeoutSocket::getFileDescriptor$ support for Conscrypt CHANGES IN THE 2.0.0 RELEASE diff --git a/mail/src/main/java/com/sun/mail/util/WriteTimeoutSocket.java b/mail/src/main/java/com/sun/mail/util/WriteTimeoutSocket.java index 1c84b529..bc2d97c6 100644 --- a/mail/src/main/java/com/sun/mail/util/WriteTimeoutSocket.java +++ b/mail/src/main/java/com/sun/mail/util/WriteTimeoutSocket.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -322,12 +322,20 @@ public Set> supportedOptions() { * @return the FileDescriptor object */ public FileDescriptor getFileDescriptor$() { - try { - Method m = Socket.class.getDeclaredMethod("getFileDescriptor$"); - return (FileDescriptor)m.invoke(socket); - } catch (Exception ex) { - return null; - } + //The loop handles issues with non-public classes between + //java.net.Socket and the actual socket type held in this object. + //Must inspect java.net.Socket to ensure compatiblity with old behavior. + for (Class k = socket.getClass(); k != Object.class; k = k.getSuperclass()) { + try { + Method m = k.getDeclaredMethod("getFileDescriptor$"); + if (FileDescriptor.class.isAssignableFrom(m.getReturnType())) { + //Skip setAccessible so non-public methods fail to invoke. + return (FileDescriptor) m.invoke(socket); + } + } catch (Exception ignore) { + } + } + return null; } } diff --git a/mail/src/test/java/com/sun/mail/util/WriteTimeoutSocketTest.java b/mail/src/test/java/com/sun/mail/util/WriteTimeoutSocketTest.java index ad7032bf..1320e21d 100644 --- a/mail/src/test/java/com/sun/mail/util/WriteTimeoutSocketTest.java +++ b/mail/src/test/java/com/sun/mail/util/WriteTimeoutSocketTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -18,8 +18,10 @@ import java.lang.reflect.*; +import java.io.FileDescriptor; import java.io.IOException; import java.io.InterruptedIOException; +import java.net.Socket; import java.util.Properties; import java.util.List; import java.util.ArrayList; @@ -42,6 +44,7 @@ import org.junit.rules.Timeout; import static org.junit.Assert.fail; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNotNull; /** * Test that write timeouts work. @@ -205,6 +208,41 @@ else if (j == 63) } } } + + @Test + public void testFileDescriptor$() throws Exception { + try (PublicFileSocket ps = new PublicFileSocket()) { + assertNotNull(ps.getFileDescriptor$()); + } + + testFileDescriptor$(new PublicFileSocket()); + testFileDescriptor$(new PublicFileSocket1of3()); + testFileDescriptor$(new PublicFileSocket2of3()); + testFileDescriptor$(new PublicFileSocket3of3()); + } + + private void testFileDescriptor$(Socket s) throws Exception { + try (WriteTimeoutSocket ws = new WriteTimeoutSocket(s, 1000)) { + assertNotNull(ws.getFileDescriptor$()); + } finally { + s.close(); + } + } + + private static class PublicFileSocket extends Socket { + public FileDescriptor getFileDescriptor$() { + return new FileDescriptor(); + } + } + + private static class PublicFileSocket1of3 extends PublicFileSocket { + } + + private static class PublicFileSocket2of3 extends PublicFileSocket1of3 { + } + + private static class PublicFileSocket3of3 extends PublicFileSocket2of3 { + } /** * Custom handler.