From djelinski at openjdk.org Mon Jan 2 08:14:53 2023 From: djelinski at openjdk.org (Daniel =?UTF-8?B?SmVsacWEc2tp?=) Date: Mon, 2 Jan 2023 08:14:53 GMT Subject: RFR: 6914801: IPv6 unavailable if stdin is a socket In-Reply-To: References: Message-ID: On Mon, 12 Dec 2022 20:30:05 GMT, Daniel Jeli?ski wrote: > This patch reenables IPv6 stack when stdin is an IPv4 socket. > > The code that blocked IPv6 was introduced in JDK-4673940 back when JDK could only operate with either IPv4 or IPv6 sockets, and was using `IPv6_available` to determine which socket type was in use. Now that JDK is able to operate with both IPv4 and IPv6 sockets at the same time, the check for IPv4 stdin is no longer relevant. > > Included test passes with the changes applied, fails without them. Other tier1-3 tests also pass. Happy new year! Thanks Alan for checking this. Can I get a more formal review? The test I added is basically a copy of EchoTest, except that 1) it runs only if an IPv6 socket can be opened by the harness, 2) the started application works only if it can open an IPv6 socket. I also modified the tests to use IPv4 sockets for communication when they are available. If IPv4 is not available, the test will use platform-default socket type, and should still pass. ------------- PR: https://git.openjdk.org/jdk/pull/11638 From pminborg at openjdk.org Mon Jan 2 09:08:35 2023 From: pminborg at openjdk.org (Per Minborg) Date: Mon, 2 Jan 2023 09:08:35 GMT Subject: RFR: 8299437: Make InetSocketAddressHolder shallowly immutable Message-ID: This PR proposes to make the class `java.net.InetSocketAddress.InetSocketAddressHolder` shallowly immutable ------------- Commit messages: - Make InetSocketAddressHolder shallowly immutable Changes: https://git.openjdk.org/jdk/pull/11809/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=11809&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8299437 Stats: 5 lines in 1 file changed: 0 ins; 0 del; 5 mod Patch: https://git.openjdk.org/jdk/pull/11809.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11809/head:pull/11809 PR: https://git.openjdk.org/jdk/pull/11809 From djelinski at openjdk.org Mon Jan 2 09:55:47 2023 From: djelinski at openjdk.org (Daniel =?UTF-8?B?SmVsacWEc2tp?=) Date: Mon, 2 Jan 2023 09:55:47 GMT Subject: RFR: 8299437: Make InetSocketAddressHolder shallowly immutable In-Reply-To: References: Message-ID: On Mon, 2 Jan 2023 09:00:43 GMT, Per Minborg wrote: > This PR proposes to make the class `java.net.InetSocketAddress.InetSocketAddressHolder` shallowly immutable Marked as reviewed by djelinski (Committer). ------------- PR: https://git.openjdk.org/jdk/pull/11809 From jpai at openjdk.org Mon Jan 2 10:01:47 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Mon, 2 Jan 2023 10:01:47 GMT Subject: RFR: 8299437: Make InetSocketAddressHolder shallowly immutable In-Reply-To: References: Message-ID: On Mon, 2 Jan 2023 09:00:43 GMT, Per Minborg wrote: > This PR proposes to make the class `java.net.InetSocketAddress.InetSocketAddressHolder` shallowly immutable Looks fine to me. ------------- Marked as reviewed by jpai (Reviewer). PR: https://git.openjdk.org/jdk/pull/11809 From mbaesken at openjdk.org Mon Jan 2 16:23:32 2023 From: mbaesken at openjdk.org (Matthias Baesken) Date: Mon, 2 Jan 2023 16:23:32 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area Message-ID: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> We have a couple of places where a SocketException is thrown but the cause is omitted. It would be beneficial for example in error analysis not to throw away the cause (causing exception) but to add it to the created SocketException. ------------- Commit messages: - JDK-8299475 Changes: https://git.openjdk.org/jdk/pull/11813/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=11813&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8299475 Stats: 13 lines in 4 files changed: 0 ins; 0 del; 13 mod Patch: https://git.openjdk.org/jdk/pull/11813.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11813/head:pull/11813 PR: https://git.openjdk.org/jdk/pull/11813 From alanb at openjdk.org Mon Jan 2 16:37:49 2023 From: alanb at openjdk.org (Alan Bateman) Date: Mon, 2 Jan 2023 16:37:49 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area In-Reply-To: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: <9VCHk3nkgtduGeyeawEF-WHEpojzEKLzmAK-5_9-kU0=.c115e4d5-dc23-4ea2-ad26-b369f0138a27@github.com> On Mon, 2 Jan 2023 16:16:08 GMT, Matthias Baesken wrote: > We have a couple of places where a SocketException is thrown but the cause is omitted. It would be beneficial for example in error analysis not to throw away the cause (causing exception) but to add it to the created SocketException. src/java.base/share/classes/java/net/ServerSocket.java line 697: > 695: if (thread.isVirtual() && thread.isInterrupted()) { > 696: close(); > 697: throw new SocketException("Closed by interrupt", e); The InterruptedIOException is used by the SocketImpl to communicate the interrupt to the ServerSocket. It should not be added a cause here. Same thing in the Socket code. src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java line 313: > 311: } catch (ConnectionResetException e) { > 312: connectionReset = true; > 313: throw new SocketException("Connection reset", e); This is internal exception and should not be added as a cause here. ------------- PR: https://git.openjdk.org/jdk/pull/11813 From alanb at openjdk.org Mon Jan 2 16:56:50 2023 From: alanb at openjdk.org (Alan Bateman) Date: Mon, 2 Jan 2023 16:56:50 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area In-Reply-To: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: On Mon, 2 Jan 2023 16:16:08 GMT, Matthias Baesken wrote: > We have a couple of places where a SocketException is thrown but the cause is omitted. It would be beneficial for example in error analysis not to throw away the cause (causing exception) but to add it to the created SocketException. src/java.base/share/classes/java/net/ServerSocket.java line 302: > 300: throw e; > 301: } catch (IOException e) { > 302: throw new SocketException(e.getMessage(), e); This one is probably okay although most of the stack trace of the cause will be identical to that of the SocketException so it might be confusing in logs. The equivalent in Socket might be a bit more useful as there are several SocketImpls used for client sockets. ------------- PR: https://git.openjdk.org/jdk/pull/11813 From alanb at openjdk.org Tue Jan 3 07:32:50 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 3 Jan 2023 07:32:50 GMT Subject: RFR: 8299437: Make InetSocketAddressHolder shallowly immutable In-Reply-To: References: Message-ID: <76O60yn_ZuYiK9jAC-kCVR162CDhGZtJt_mQwAeUiLU=.605528fa-1653-460f-9f1a-0c504d625ed3@github.com> On Mon, 2 Jan 2023 09:00:43 GMT, Per Minborg wrote: > This PR proposes to make the class `java.net.InetSocketAddress.InetSocketAddressHolder` shallowly immutable Well spotted, I don't know why these fields weren't final from the start. ------------- Marked as reviewed by alanb (Reviewer). PR: https://git.openjdk.org/jdk/pull/11809 From mbaesken at openjdk.org Tue Jan 3 08:29:13 2023 From: mbaesken at openjdk.org (Matthias Baesken) Date: Tue, 3 Jan 2023 08:29:13 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v2] In-Reply-To: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: > We have a couple of places where a SocketException is thrown but the cause is omitted. It would be beneficial for example in error analysis not to throw away the cause (causing exception) but to add it to the created SocketException. Matthias Baesken has updated the pull request incrementally with one additional commit since the last revision: do not enhance some internal exceptions ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11813/files - new: https://git.openjdk.org/jdk/pull/11813/files/b8933007..5c4c58c3 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11813&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11813&range=00-01 Stats: 4 lines in 2 files changed: 0 ins; 0 del; 4 mod Patch: https://git.openjdk.org/jdk/pull/11813.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11813/head:pull/11813 PR: https://git.openjdk.org/jdk/pull/11813 From mbaesken at openjdk.org Tue Jan 3 08:29:14 2023 From: mbaesken at openjdk.org (Matthias Baesken) Date: Tue, 3 Jan 2023 08:29:14 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v2] In-Reply-To: <9VCHk3nkgtduGeyeawEF-WHEpojzEKLzmAK-5_9-kU0=.c115e4d5-dc23-4ea2-ad26-b369f0138a27@github.com> References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> <9VCHk3nkgtduGeyeawEF-WHEpojzEKLzmAK-5_9-kU0=.c115e4d5-dc23-4ea2-ad26-b369f0138a27@github.com> Message-ID: On Mon, 2 Jan 2023 16:34:26 GMT, Alan Bateman wrote: >> Matthias Baesken has updated the pull request incrementally with one additional commit since the last revision: >> >> do not enhance some internal exceptions > > src/java.base/share/classes/java/net/ServerSocket.java line 697: > >> 695: if (thread.isVirtual() && thread.isInterrupted()) { >> 696: close(); >> 697: throw new SocketException("Closed by interrupt", e); > > The InterruptedIOException is used by the SocketImpl to communicate the interrupt to the ServerSocket. It should not be added a cause here. Same thing in the Socket code. Hi Alan, I removed this one. ------------- PR: https://git.openjdk.org/jdk/pull/11813 From mbaesken at openjdk.org Tue Jan 3 08:32:49 2023 From: mbaesken at openjdk.org (Matthias Baesken) Date: Tue, 3 Jan 2023 08:32:49 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v2] In-Reply-To: References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: On Tue, 3 Jan 2023 08:29:13 GMT, Matthias Baesken wrote: >> We have a couple of places where a SocketException is thrown but the cause is omitted. It would be beneficial for example in error analysis not to throw away the cause (causing exception) but to add it to the created SocketException. > > Matthias Baesken has updated the pull request incrementally with one additional commit since the last revision: > > do not enhance some internal exceptions Hi Alan, I removed the InterruptedIOException enhancement . Regarding the ConnectionResetException in NioSocketImpl.java, it is not so bad to know what tryRead caused it. So why not add it ? Additionally we could also add the errno (EPIPE or ECONNRESET) to the exception message to get a better picture of the error situation (see java.base/unix/native/libnio/ch/SocketDispatcher.c ). ------------- PR: https://git.openjdk.org/jdk/pull/11813 From alanb at openjdk.org Tue Jan 3 08:49:48 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 3 Jan 2023 08:49:48 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v2] In-Reply-To: References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: <33d0KGFguWmBDc_rc4XUZ-El_5BjSCg7la9uKUlUe8A=.d4acb899-07a5-4786-bb4e-9b3f200ce76a@github.com> On Tue, 3 Jan 2023 08:29:41 GMT, Matthias Baesken wrote: > Hi Alan, I removed the InterruptedIOException enhancement . Regarding the ConnectionResetException in NioSocketImpl.java, it is not so bad to know what tryRead caused it. So why not add it ? > > Additionally we could also add the errno (EPIPE or ECONNRESET) to the exception message to get a better picture of the error situation (see java.base/unix/native/libnio/ch/SocketDispatcher.c ). sun.net.ConnectionResetException is used to communicate the error from the native code to the socket impl. It's part of an internal contract and never ended to be leak out to user code. There have been discussions every few yers about introducing a specific SocketException for the "connection reset" scenario and maybe it is time to look at that again. ------------- PR: https://git.openjdk.org/jdk/pull/11813 From mbaesken at openjdk.org Tue Jan 3 08:49:49 2023 From: mbaesken at openjdk.org (Matthias Baesken) Date: Tue, 3 Jan 2023 08:49:49 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v2] In-Reply-To: <33d0KGFguWmBDc_rc4XUZ-El_5BjSCg7la9uKUlUe8A=.d4acb899-07a5-4786-bb4e-9b3f200ce76a@github.com> References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> <33d0KGFguWmBDc_rc4XUZ-El_5BjSCg7la9uKUlUe8A=.d4acb899-07a5-4786-bb4e-9b3f200ce76a@github.com> Message-ID: <9wo0tPZiqusi_3nWX7UiaM1rXvmw7FdUKOhaJOHKTtI=.36aaa679-5089-4540-bac9-3119866de474@github.com> On Tue, 3 Jan 2023 08:43:04 GMT, Alan Bateman wrote: > > Hi Alan, I removed the InterruptedIOException enhancement . Regarding the ConnectionResetException in NioSocketImpl.java, it is not so bad to know what tryRead caused it. So why not add it ? > > Additionally we could also add the errno (EPIPE or ECONNRESET) to the exception message to get a better picture of the error situation (see java.base/unix/native/libnio/ch/SocketDispatcher.c ). > > sun.net.ConnectionResetException is used to communicate the error from the native code to the socket impl. It's part of an internal contract and never ended to be leak out to user code. > > There have been discussions every few yers about introducing a specific SocketException for the "connection reset" scenario and maybe it is time to look at that again. Hi Alan, do you mean some new class like java/net/SocketConnectionResetException.java (or a more suitable name) ? ------------- PR: https://git.openjdk.org/jdk/pull/11813 From alanb at openjdk.org Tue Jan 3 08:49:52 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 3 Jan 2023 08:49:52 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v2] In-Reply-To: References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: On Tue, 3 Jan 2023 08:29:13 GMT, Matthias Baesken wrote: >> We have a couple of places where a SocketException is thrown but the cause is omitted. It would be beneficial for example in error analysis not to throw away the cause (causing exception) but to add it to the created SocketException. > > Matthias Baesken has updated the pull request incrementally with one additional commit since the last revision: > > do not enhance some internal exceptions src/java.base/share/classes/java/net/Socket.java line 535: > 533: created = true; > 534: } catch (IOException e) { > 535: throw new SocketException(e.getMessage(), e); For this one, you could `catch (SocketException e) { throw e; }` as the exception from the impl will be a SocketException anyway. That would help avoid the confusing cause. ------------- PR: https://git.openjdk.org/jdk/pull/11813 From mbaesken at openjdk.org Tue Jan 3 08:52:48 2023 From: mbaesken at openjdk.org (Matthias Baesken) Date: Tue, 3 Jan 2023 08:52:48 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v2] In-Reply-To: References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: On Tue, 3 Jan 2023 08:45:11 GMT, Alan Bateman wrote: >> Matthias Baesken has updated the pull request incrementally with one additional commit since the last revision: >> >> do not enhance some internal exceptions > > src/java.base/share/classes/java/net/Socket.java line 535: > >> 533: created = true; >> 534: } catch (IOException e) { >> 535: throw new SocketException(e.getMessage(), e); > > For this one, you could `catch (SocketException e) { throw e; }` as the exception from the impl will be a SocketException anyway. That would help avoid the confusing cause. Hi Alan, createImpl throws SocketException anyway, so can't we just remove the catch completely in this case ? Or are there other IOExceptions? ------------- PR: https://git.openjdk.org/jdk/pull/11813 From alanb at openjdk.org Tue Jan 3 09:18:49 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 3 Jan 2023 09:18:49 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v2] In-Reply-To: <9wo0tPZiqusi_3nWX7UiaM1rXvmw7FdUKOhaJOHKTtI=.36aaa679-5089-4540-bac9-3119866de474@github.com> References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> <33d0KGFguWmBDc_rc4XUZ-El_5BjSCg7la9uKUlUe8A=.d4acb899-07a5-4786-bb4e-9b3f200ce76a@github.com> <9wo0tPZiqusi_3nWX7UiaM1rXvmw7FdUKOhaJOHKTtI=.36aaa679-5089-4540-bac9-3119866de474@github.com> Message-ID: On Tue, 3 Jan 2023 08:47:24 GMT, Matthias Baesken wrote: > Hi Alan, do you mean some new class like java/net/SocketConnectionResetException.java (or a more suitable name) ? Yes, although we never managed to come up to agreement on whether to introduce a standard exception. For now, it is important to not leak the internal exception - that is there solely as an internal contract. ------------- PR: https://git.openjdk.org/jdk/pull/11813 From alanb at openjdk.org Tue Jan 3 09:18:51 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 3 Jan 2023 09:18:51 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v2] In-Reply-To: References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: <-prXUhEkBRGTgAY6en6NgIvsR88jcYO7h-sX_3PQyCE=.15eab4ba-7ca2-4304-84b6-2248cd7658f4@github.com> On Tue, 3 Jan 2023 08:50:10 GMT, Matthias Baesken wrote: >> src/java.base/share/classes/java/net/Socket.java line 535: >> >>> 533: created = true; >>> 534: } catch (IOException e) { >>> 535: throw new SocketException(e.getMessage(), e); >> >> For this one, you could `catch (SocketException e) { throw e; }` as the exception from the impl will be a SocketException anyway. That would help avoid the confusing cause. > > Hi Alan, createImpl throws SocketException anyway, so can't we just remove the catch completely in this case ? > Or are there other IOExceptions? Our SocketImpls mostly throw SocketException so inserting the catch of SocketException will avoid the translation for most cases. ------------- PR: https://git.openjdk.org/jdk/pull/11813 From pminborg at openjdk.org Tue Jan 3 10:03:54 2023 From: pminborg at openjdk.org (Per Minborg) Date: Tue, 3 Jan 2023 10:03:54 GMT Subject: Integrated: 8299437: Make InetSocketAddressHolder shallowly immutable In-Reply-To: References: Message-ID: On Mon, 2 Jan 2023 09:00:43 GMT, Per Minborg wrote: > This PR proposes to make the class `java.net.InetSocketAddress.InetSocketAddressHolder` shallowly immutable This pull request has now been integrated. Changeset: a9ce7726 Author: Per Minborg Committer: Jaikiran Pai URL: https://git.openjdk.org/jdk/commit/a9ce7726a722c9deba659dff3f87b7e72d6c4997 Stats: 5 lines in 1 file changed: 0 ins; 0 del; 5 mod 8299437: Make InetSocketAddressHolder shallowly immutable Reviewed-by: djelinski, jpai, alanb ------------- PR: https://git.openjdk.org/jdk/pull/11809 From mbaesken at openjdk.org Tue Jan 3 10:27:48 2023 From: mbaesken at openjdk.org (Matthias Baesken) Date: Tue, 3 Jan 2023 10:27:48 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v2] In-Reply-To: <-prXUhEkBRGTgAY6en6NgIvsR88jcYO7h-sX_3PQyCE=.15eab4ba-7ca2-4304-84b6-2248cd7658f4@github.com> References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> <-prXUhEkBRGTgAY6en6NgIvsR88jcYO7h-sX_3PQyCE=.15eab4ba-7ca2-4304-84b6-2248cd7658f4@github.com> Message-ID: <-C1DFKb_LTBpBjK8ss91yCGKxyjpEORuo5AOsabDAYg=.bef9cebe-0e24-4803-9cea-d454f4528a3f@github.com> On Tue, 3 Jan 2023 09:14:11 GMT, Alan Bateman wrote: >> Hi Alan, createImpl throws SocketException anyway, so can't we just remove the catch completely in this case ? >> Or are there other IOExceptions? > > Our SocketImpls mostly throw SocketException so inserting the catch of SocketException will avoid the translation for most cases. Replacing the IOException does not work, this even leads to a compile error " unreported exception IOException" ; so I guess the catch (SocketException e) needs to be added to the IOException ; not so nice. ------------- PR: https://git.openjdk.org/jdk/pull/11813 From alanb at openjdk.org Tue Jan 3 10:31:49 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 3 Jan 2023 10:31:49 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v2] In-Reply-To: <-C1DFKb_LTBpBjK8ss91yCGKxyjpEORuo5AOsabDAYg=.bef9cebe-0e24-4803-9cea-d454f4528a3f@github.com> References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> <-prXUhEkBRGTgAY6en6NgIvsR88jcYO7h-sX_3PQyCE=.15eab4ba-7ca2-4304-84b6-2248cd7658f4@github.com> <-C1DFKb_LTBpBjK8ss91yCGKxyjpEORuo5AOsabDAYg=.bef9cebe-0e24-4803-9cea-d454f4528a3f@github.com> Message-ID: On Tue, 3 Jan 2023 10:25:21 GMT, Matthias Baesken wrote: >> Our SocketImpls mostly throw SocketException so inserting the catch of SocketException will avoid the translation for most cases. > > Replacing the IOException does not work, this even leads to a compile error " unreported exception IOException" ; so I guess the catch (SocketException e) needs to be added to the IOException ; not so nice. I didn't mean to replace it, I meant to insert of catch of SocketException before the IOException. That will avoid throwing SocketException with cause SocketException. If you look at the equivalent in ServerSocket then you'll see what I mean. ------------- PR: https://git.openjdk.org/jdk/pull/11813 From mbaesken at openjdk.org Tue Jan 3 10:47:11 2023 From: mbaesken at openjdk.org (Matthias Baesken) Date: Tue, 3 Jan 2023 10:47:11 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v3] In-Reply-To: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: > We have a couple of places where a SocketException is thrown but the cause is omitted. It would be beneficial for example in error analysis not to throw away the cause (causing exception) but to add it to the created SocketException. Matthias Baesken has updated the pull request incrementally with one additional commit since the last revision: re-throw SocketException, remove one enhancement because it is meant to be internal ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11813/files - new: https://git.openjdk.org/jdk/pull/11813/files/5c4c58c3..4eb84f37 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11813&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11813&range=01-02 Stats: 4 lines in 2 files changed: 2 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/11813.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11813/head:pull/11813 PR: https://git.openjdk.org/jdk/pull/11813 From michaelm at openjdk.org Tue Jan 3 12:38:52 2023 From: michaelm at openjdk.org (Michael McMahon) Date: Tue, 3 Jan 2023 12:38:52 GMT Subject: RFR: 6914801: IPv6 unavailable if stdin is a socket In-Reply-To: References: Message-ID: On Mon, 2 Jan 2023 08:11:39 GMT, Daniel Jeli?ski wrote: > Happy new year! Thanks Alan for checking this. Can I get a more formal review? > > The test I added is basically a copy of EchoTest, except that 1) it runs only if an IPv6 socket can be opened by the harness, 2) the started application works only if it can open an IPv6 socket. I also modified the tests to use IPv4 sockets for communication when they are available. If IPv4 is not available, the test will use platform-default socket type, and should still pass. Checking it now. ------------- PR: https://git.openjdk.org/jdk/pull/11638 From alanb at openjdk.org Tue Jan 3 13:48:51 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 3 Jan 2023 13:48:51 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v3] In-Reply-To: References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: <-JJb5gUUjle7DgCqjXuPm9h6hnCWHMEBm6VlrYbihzs=.edb76d2e-c31f-48db-97cb-0671bd4e1eae@github.com> On Tue, 3 Jan 2023 10:47:11 GMT, Matthias Baesken wrote: >> We have a couple of places where a SocketException is thrown but the cause is omitted. It would be beneficial for example in error analysis not to throw away the cause (causing exception) but to add it to the created SocketException. > > Matthias Baesken has updated the pull request incrementally with one additional commit since the last revision: > > re-throw SocketException, remove one enhancement because it is meant to be internal src/java.base/share/classes/java/net/Socket.java line 537: > 535: throw e; > 536: } catch (IOException e) { > 537: throw new SocketException(e.getMessage()); I can't immediately think of real cases where a non-SocketException is thrown when creating a SocketImpl but for consistency with the equivalent in ServerSocket then you could add the cause here too. src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java line 413: > 411: throw e; > 412: } catch (IOException ioe) { > 413: throw new SocketException(ioe.getMessage(), ioe); I'm in two minds on whether this is a good idea or not because the stack trace of the cause is mostly the same as the SocketException, e.g. right now we get a clear stack trace like this: Exception in thread "main" java.net.SocketException: Broken pipe at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:413) at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:433) at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:812) at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1192) at java.base/java.io.OutputStream.write(OutputStream.java:124) but with the change we get a cause with almost the same stack trace: Exception in thread "main" java.net.SocketException: Broken pipe at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:413) at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:433) at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:812) at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1192) at java.base/java.io.OutputStream.write(OutputStream.java:124) Caused by: java.io.IOException: Broken pipe at java.base/sun.nio.ch.SocketDispatcher.write0(Native Method) at java.base/sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:62) at java.base/sun.nio.ch.NioSocketImpl.tryWrite(NioSocketImpl.java:388) at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:404) at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:433) at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:812) at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1192) at java.base/java.io.OutputStream.write(OutputStream.java:124) The reason for the translation from IOException to SocketException is so that the SocketImpl added via JEP 353 throws the same specific exceptions as the legacy implementation. We were concerned there may be older code assuming that read/write throw SocketException. So one idea here is to avoid the confusing cause is to use the stack trace from the IOException, as in: var e = new SocketException(ioe.getMessage()); e.setStackTrace(ioe.getStackTrace()); throw e; which gives us a clear stack trace like we have now: Exception in thread "main" java.net.SocketException: Broken pipe at java.base/sun.nio.ch.SocketDispatcher.write0(Native Method) at java.base/sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:62) at java.base/sun.nio.ch.NioSocketImpl.tryWrite(NioSocketImpl.java:388) at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:404) at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:435) at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:814) at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1192) at java.base/java.io.OutputStream.write(OutputStream.java:124) ------------- PR: https://git.openjdk.org/jdk/pull/11813 From mbaesken at openjdk.org Tue Jan 3 13:57:20 2023 From: mbaesken at openjdk.org (Matthias Baesken) Date: Tue, 3 Jan 2023 13:57:20 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v4] In-Reply-To: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: > We have a couple of places where a SocketException is thrown but the cause is omitted. It would be beneficial for example in error analysis not to throw away the cause (causing exception) but to add it to the created SocketException. Matthias Baesken has updated the pull request incrementally with one additional commit since the last revision: Adjust Socket createImpl again ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11813/files - new: https://git.openjdk.org/jdk/pull/11813/files/4eb84f37..8af8a34d Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11813&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11813&range=02-03 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/11813.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11813/head:pull/11813 PR: https://git.openjdk.org/jdk/pull/11813 From michaelm at openjdk.org Tue Jan 3 18:29:49 2023 From: michaelm at openjdk.org (Michael McMahon) Date: Tue, 3 Jan 2023 18:29:49 GMT Subject: RFR: 6914801: IPv6 unavailable if stdin is a socket In-Reply-To: References: Message-ID: <-WB063qWyxVeQzaciIVXaQRtNPOZRxIQd5b0lUNdZjY=.d07726ef-a3f7-4366-aecb-34c47a78288f@github.com> On Mon, 12 Dec 2022 20:30:05 GMT, Daniel Jeli?ski wrote: > This patch reenables IPv6 stack when stdin is an IPv4 socket. > > The code that blocked IPv6 was introduced in JDK-4673940 back when JDK could only operate with either IPv4 or IPv6 sockets, and was using `IPv6_available` to determine which socket type was in use. Now that JDK is able to operate with both IPv4 and IPv6 sockets at the same time, the check for IPv4 stdin is no longer relevant. > > Included test passes with the changes applied, fails without them. Other tier1-3 tests also pass. test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.java line 112: > 110: try (ServerSocketChannel ssc = ch) { > 111: ssc.socket().bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); > 112: SocketChannel sc1 = SocketChannel.open(ssc.getLocalAddress()); Could we add some logging/printlns here to indicate the protocol family of `ch` or its local address, to aid in debugging if we ever have problems with the test (eg on IPv6 only systems)? ------------- PR: https://git.openjdk.org/jdk/pull/11638 From alanb at openjdk.org Tue Jan 3 20:38:51 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 3 Jan 2023 20:38:51 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v4] In-Reply-To: References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: On Tue, 3 Jan 2023 13:57:20 GMT, Matthias Baesken wrote: >> We have a couple of places where a SocketException is thrown but the cause is omitted. It would be beneficial for example in error analysis not to throw away the cause (causing exception) but to add it to the created SocketException. > > Matthias Baesken has updated the pull request incrementally with one additional commit since the last revision: > > Adjust Socket createImpl again The changes in [8af8a34d] to Socket, ServerSocket and SocksSocketImpl looks okay. I think the changes to NioSocketImpl will lead to confusing output as the cause will be almost identify to the SocketException. I assume your goal with the change is to get the deepest implementation frames into the stack trace. They would be there if read/write threw IOException but we decided in JEP 353 to throw the more specific SocketException to maintain historical behavior. So maybe we could try this instead - this will throw the SocketException with the stack trace from the IOException so it will include the deepest frames: diff --git a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java index b2531135b03..f96d8380f29 100644 --- a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java @@ -312,7 +312,8 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp connectionReset = true; throw new SocketException("Connection reset"); } catch (IOException ioe) { - throw new SocketException(ioe.getMessage()); + // throw SocketException to maintain compatibility + throw asSocketException(ioe); } finally { endRead(n > 0); } @@ -410,7 +411,8 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp } catch (InterruptedIOException e) { throw e; } catch (IOException ioe) { - throw new SocketException(ioe.getMessage()); + // throw SocketException to maintain compatibility + throw asSocketException(ioe); } finally { endWrite(n > 0); } @@ -1081,10 +1083,8 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp default: throw new SocketException("Unknown option " + opt); } - } catch (SocketException e) { - throw e; } catch (IllegalArgumentException | IOException e) { - throw new SocketException(e.getMessage()); + throw asSocketException(e); } } } @@ -1133,10 +1133,8 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp default: throw new SocketException("Unknown option " + opt); } - } catch (SocketException e) { - throw e; } catch (IllegalArgumentException | IOException e) { - throw new SocketException(e.getMessage()); + throw asSocketException(e); } } } @@ -1249,6 +1247,19 @@ public final class NioSocketImpl extends SocketImpl implements PlatformSocketImp return remainingNanos; } + /** + * Creates a SocketException from the given exception. + */ + private static SocketException asSocketException(Exception e) { + if (e instanceof SocketException se) { + return se; + } else { + var se = new SocketException(e.getMessage()); + se.setStackTrace(e.getStackTrace()); + return se; + } + } + /** * Returns the socket protocol family. */ ------------- PR: https://git.openjdk.org/jdk/pull/11813 From mbaesken at openjdk.org Wed Jan 4 09:04:05 2023 From: mbaesken at openjdk.org (Matthias Baesken) Date: Wed, 4 Jan 2023 09:04:05 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v5] In-Reply-To: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: <07WiH0DJiZjyVoDtlT82cvR-dYzua9awfaAXpwql4MY=.3e8badbb-994b-45f8-a816-c026fe4aa3bf@github.com> > We have a couple of places where a SocketException is thrown but the cause is omitted. It would be beneficial for example in error analysis not to throw away the cause (causing exception) but to add it to the created SocketException. Matthias Baesken has updated the pull request incrementally with one additional commit since the last revision: NioSocketImpl shorten extended exception ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11813/files - new: https://git.openjdk.org/jdk/pull/11813/files/8af8a34d..62916a71 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11813&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11813&range=03-04 Stats: 3 lines in 1 file changed: 2 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/11813.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11813/head:pull/11813 PR: https://git.openjdk.org/jdk/pull/11813 From mbaesken at openjdk.org Wed Jan 4 09:04:06 2023 From: mbaesken at openjdk.org (Matthias Baesken) Date: Wed, 4 Jan 2023 09:04:06 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v3] In-Reply-To: <-JJb5gUUjle7DgCqjXuPm9h6hnCWHMEBm6VlrYbihzs=.edb76d2e-c31f-48db-97cb-0671bd4e1eae@github.com> References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> <-JJb5gUUjle7DgCqjXuPm9h6hnCWHMEBm6VlrYbihzs=.edb76d2e-c31f-48db-97cb-0671bd4e1eae@github.com> Message-ID: On Tue, 3 Jan 2023 13:45:13 GMT, Alan Bateman wrote: >> Matthias Baesken has updated the pull request incrementally with one additional commit since the last revision: >> >> re-throw SocketException, remove one enhancement because it is meant to be internal > > src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java line 413: > >> 411: throw e; >> 412: } catch (IOException ioe) { >> 413: throw new SocketException(ioe.getMessage(), ioe); > > I'm in two minds on whether this is a good idea or not because the stack trace of the cause is mostly the same as the SocketException, e.g. right now we get a clear stack trace like this: > > Exception in thread "main" java.net.SocketException: Broken pipe > at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:413) > at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:433) > at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:812) > at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1192) > at java.base/java.io.OutputStream.write(OutputStream.java:124) > > > but with the change we get a cause with almost the same stack trace: > > Exception in thread "main" java.net.SocketException: Broken pipe > at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:413) > at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:433) > at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:812) > at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1192) > at java.base/java.io.OutputStream.write(OutputStream.java:124) > Caused by: java.io.IOException: Broken pipe > at java.base/sun.nio.ch.SocketDispatcher.write0(Native Method) > at java.base/sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:62) > at java.base/sun.nio.ch.NioSocketImpl.tryWrite(NioSocketImpl.java:388) > at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:404) > at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:433) > at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:812) > at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1192) > at java.base/java.io.OutputStream.write(OutputStream.java:124) > > > The reason for the translation from IOException to SocketException is so that the SocketImpl added via JEP 353 throws the same specific exceptions as the legacy implementation. We were concerned there may be older code assuming that read/write throw SocketException. So one idea here is to avoid the confusing cause is to use the stack trace from the IOException, as in: > > var e = new SocketException(ioe.getMessage()); > e.setStackTrace(ioe.getStackTrace()); > throw e; > > which gives us a clear stack trace like we have now: > > Exception in thread "main" java.net.SocketException: Broken pipe > at java.base/sun.nio.ch.SocketDispatcher.write0(Native Method) > at java.base/sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:62) > at java.base/sun.nio.ch.NioSocketImpl.tryWrite(NioSocketImpl.java:388) > at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:404) > at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:435) > at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:814) > at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1192) > at java.base/java.io.OutputStream.write(OutputStream.java:124) Hi Alan, I adjusted this coding following your suggestion to use setStackTrace. ------------- PR: https://git.openjdk.org/jdk/pull/11813 From alanb at openjdk.org Wed Jan 4 10:03:49 2023 From: alanb at openjdk.org (Alan Bateman) Date: Wed, 4 Jan 2023 10:03:49 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v3] In-Reply-To: References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> <-JJb5gUUjle7DgCqjXuPm9h6hnCWHMEBm6VlrYbihzs=.edb76d2e-c31f-48db-97cb-0671bd4e1eae@github.com> Message-ID: On Wed, 4 Jan 2023 08:59:51 GMT, Matthias Baesken wrote: > Hi Alan, I adjusted this coding following your suggestion to use setStackTrace. That's just one of them. In a later comment I pasted in asSocketException and changed all 4 cases to use it, maybe you could try that. The right thing is of course to drop the translation to SocketException as anything using read/write has to deal with IOException anyway, it's really just a concern that older code may having special handling of SocketException of undocumented, but longstanding, behavior in older JDK releases. ------------- PR: https://git.openjdk.org/jdk/pull/11813 From mbaesken at openjdk.org Wed Jan 4 11:36:13 2023 From: mbaesken at openjdk.org (Matthias Baesken) Date: Wed, 4 Jan 2023 11:36:13 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v6] In-Reply-To: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: > We have a couple of places where a SocketException is thrown but the cause is omitted. It would be beneficial for example in error analysis not to throw away the cause (causing exception) but to add it to the created SocketException. Matthias Baesken has updated the pull request incrementally with one additional commit since the last revision: Introduce asSocketException in nio ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11813/files - new: https://git.openjdk.org/jdk/pull/11813/files/62916a71..655cf6ff Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11813&range=05 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11813&range=04-05 Stats: 20 lines in 1 file changed: 14 ins; 1 del; 5 mod Patch: https://git.openjdk.org/jdk/pull/11813.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11813/head:pull/11813 PR: https://git.openjdk.org/jdk/pull/11813 From mbaesken at openjdk.org Wed Jan 4 11:43:59 2023 From: mbaesken at openjdk.org (Matthias Baesken) Date: Wed, 4 Jan 2023 11:43:59 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v3] In-Reply-To: References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> <-JJb5gUUjle7DgCqjXuPm9h6hnCWHMEBm6VlrYbihzs=.edb76d2e-c31f-48db-97cb-0671bd4e1eae@github.com> Message-ID: On Wed, 4 Jan 2023 10:00:51 GMT, Alan Bateman wrote: >> Hi Alan, I adjusted this coding following your suggestion to use setStackTrace. > >> Hi Alan, I adjusted this coding following your suggestion to use setStackTrace. > > That's just one of them. In a later comment I pasted in asSocketException and changed all 4 cases to use it, maybe you could try that. The right thing is of course to drop the translation to SocketException as anything using read/write has to deal with IOException anyway, it's really just a concern that older code may having special handling of SocketException of undocumented, but longstanding, behavior in older JDK releases. Sorry Alan, seems I somehow missed that. I pushed a new commit including asSocketException . I wonder, could asSocketException in the form of asOtherException maybe be a useful generics that covers multiple exception classes (but that would be something for another PR) ? public static T asOtherException(Exception e, T n) { ... } (maybe we could omit the second param somehow, not sure.) ------------- PR: https://git.openjdk.org/jdk/pull/11813 From alanb at openjdk.org Wed Jan 4 15:03:52 2023 From: alanb at openjdk.org (Alan Bateman) Date: Wed, 4 Jan 2023 15:03:52 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v6] In-Reply-To: References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: On Wed, 4 Jan 2023 11:36:13 GMT, Matthias Baesken wrote: >> We have a couple of places where a SocketException is thrown but the cause is omitted. It would be beneficial for example in error analysis not to throw away the cause (causing exception) but to add it to the created SocketException. > > Matthias Baesken has updated the pull request incrementally with one additional commit since the last revision: > > Introduce asSocketException in nio Marked as reviewed by alanb (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/11813 From alanb at openjdk.org Wed Jan 4 15:03:53 2023 From: alanb at openjdk.org (Alan Bateman) Date: Wed, 4 Jan 2023 15:03:53 GMT Subject: RFR: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area [v3] In-Reply-To: References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> <-JJb5gUUjle7DgCqjXuPm9h6hnCWHMEBm6VlrYbihzs=.edb76d2e-c31f-48db-97cb-0671bd4e1eae@github.com> Message-ID: On Wed, 4 Jan 2023 11:41:10 GMT, Matthias Baesken wrote: >>> Hi Alan, I adjusted this coding following your suggestion to use setStackTrace. >> >> That's just one of them. In a later comment I pasted in asSocketException and changed all 4 cases to use it, maybe you could try that. The right thing is of course to drop the translation to SocketException as anything using read/write has to deal with IOException anyway, it's really just a concern that older code may having special handling of SocketException of undocumented, but longstanding, behavior in older JDK releases. > > Sorry Alan, seems I somehow missed that. I pushed a new commit including asSocketException . > > > I wonder, could asSocketException in the form of asOtherException maybe be a useful generics that covers multiple exception classes (but that would be something for another PR) ? > > public static T asOtherException(Exception e, T n) { > ... > } > > (maybe we could omit the second param somehow, not sure.) If there were other translations needed then it might be useful but I don't think we need it for this change. So I think go with what you have now and we can re-visit it another time if needed, hopefully to remove it (at least for read/write) as the translation shouldn't be required. ------------- PR: https://git.openjdk.org/jdk/pull/11813 From djelinski at openjdk.org Wed Jan 4 16:18:58 2023 From: djelinski at openjdk.org (Daniel =?UTF-8?B?SmVsacWEc2tp?=) Date: Wed, 4 Jan 2023 16:18:58 GMT Subject: RFR: 6914801: IPv6 unavailable if stdin is a socket [v2] In-Reply-To: References: Message-ID: <44x9XnQFeKdHaydNCCCjkrc5n4zcupMwbd3a5qYY4qw=.af9b8ef3-b4b1-44d6-9855-0de0a6fb7b3a@github.com> > This patch reenables IPv6 stack when stdin is an IPv4 socket. > > The code that blocked IPv6 was introduced in JDK-4673940 back when JDK could only operate with either IPv4 or IPv6 sockets, and was using `IPv6_available` to determine which socket type was in use. Now that JDK is able to operate with both IPv4 and IPv6 sockets at the same time, the check for IPv4 stdin is no longer relevant. > > Included test passes with the changes applied, fails without them. Other tier1-3 tests also pass. Daniel Jeli?ski has updated the pull request incrementally with one additional commit since the last revision: Additional logging ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11638/files - new: https://git.openjdk.org/jdk/pull/11638/files/ba35ebc2..f8866cf4 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11638&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11638&range=00-01 Stats: 4 lines in 1 file changed: 3 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/11638.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11638/head:pull/11638 PR: https://git.openjdk.org/jdk/pull/11638 From djelinski at openjdk.org Wed Jan 4 16:18:59 2023 From: djelinski at openjdk.org (Daniel =?UTF-8?B?SmVsacWEc2tp?=) Date: Wed, 4 Jan 2023 16:18:59 GMT Subject: RFR: 6914801: IPv6 unavailable if stdin is a socket [v2] In-Reply-To: <-WB063qWyxVeQzaciIVXaQRtNPOZRxIQd5b0lUNdZjY=.d07726ef-a3f7-4366-aecb-34c47a78288f@github.com> References: <-WB063qWyxVeQzaciIVXaQRtNPOZRxIQd5b0lUNdZjY=.d07726ef-a3f7-4366-aecb-34c47a78288f@github.com> Message-ID: On Tue, 3 Jan 2023 18:26:36 GMT, Michael McMahon wrote: >> Daniel Jeli?ski has updated the pull request incrementally with one additional commit since the last revision: >> >> Additional logging > > test/jdk/java/nio/channels/spi/SelectorProvider/inheritedChannel/Launcher.java line 112: > >> 110: try (ServerSocketChannel ssc = ch) { >> 111: ssc.socket().bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); >> 112: SocketChannel sc1 = SocketChannel.open(ssc.getLocalAddress()); > > Could we add some logging/printlns here to indicate the protocol family of `ch` or its local address, to aid in debugging if we ever have problems with the test (eg on IPv6 only systems)? Added; now it produces output like: Using INET (IPv4) channel Socket bound to /127.0.0.1:44179 ------------- PR: https://git.openjdk.org/jdk/pull/11638 From mbaesken at openjdk.org Thu Jan 5 08:29:56 2023 From: mbaesken at openjdk.org (Matthias Baesken) Date: Thu, 5 Jan 2023 08:29:56 GMT Subject: Integrated: JDK-8299475: Enhance SocketException by cause where it is missing in net and nio area In-Reply-To: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> References: <_9rfakta5KnOpV04qXWXB31n4hmIXHaFFctkixmnXs4=.4bd0a2f7-d584-4260-bb69-cf2bde8762a2@github.com> Message-ID: On Mon, 2 Jan 2023 16:16:08 GMT, Matthias Baesken wrote: > We have a couple of places where a SocketException is thrown but the cause is omitted. It would be beneficial for example in error analysis not to throw away the cause (causing exception) but to add it to the created SocketException. This pull request has now been integrated. Changeset: c929d8be Author: Matthias Baesken URL: https://git.openjdk.org/jdk/commit/c929d8be5d19f2030406eb5c19f854e672c7a547 Stats: 25 lines in 4 files changed: 17 ins; 0 del; 8 mod 8299475: Enhance SocketException by cause where it is missing in net and nio area Reviewed-by: alanb ------------- PR: https://git.openjdk.org/jdk/pull/11813 From michaelm at openjdk.org Thu Jan 5 09:46:50 2023 From: michaelm at openjdk.org (Michael McMahon) Date: Thu, 5 Jan 2023 09:46:50 GMT Subject: RFR: 6914801: IPv6 unavailable if stdin is a socket [v2] In-Reply-To: <44x9XnQFeKdHaydNCCCjkrc5n4zcupMwbd3a5qYY4qw=.af9b8ef3-b4b1-44d6-9855-0de0a6fb7b3a@github.com> References: <44x9XnQFeKdHaydNCCCjkrc5n4zcupMwbd3a5qYY4qw=.af9b8ef3-b4b1-44d6-9855-0de0a6fb7b3a@github.com> Message-ID: <0lrZBK5ZjXs6FEVRwQ_qFmGw3_8W0x3oP8Cl23vJIXU=.282bb089-98e5-4307-9e09-33159f87ba4b@github.com> On Wed, 4 Jan 2023 16:18:58 GMT, Daniel Jeli?ski wrote: >> This patch reenables IPv6 stack when stdin is an IPv4 socket. >> >> The code that blocked IPv6 was introduced in JDK-4673940 back when JDK could only operate with either IPv4 or IPv6 sockets, and was using `IPv6_available` to determine which socket type was in use. Now that JDK is able to operate with both IPv4 and IPv6 sockets at the same time, the check for IPv4 stdin is no longer relevant. >> >> Included test passes with the changes applied, fails without them. Other tier1-3 tests also pass. > > Daniel Jeli?ski has updated the pull request incrementally with one additional commit since the last revision: > > Additional logging LGTM ------------- Marked as reviewed by michaelm (Reviewer). PR: https://git.openjdk.org/jdk/pull/11638 From alanb at openjdk.org Thu Jan 5 09:51:54 2023 From: alanb at openjdk.org (Alan Bateman) Date: Thu, 5 Jan 2023 09:51:54 GMT Subject: RFR: 6914801: IPv6 unavailable if stdin is a socket In-Reply-To: References: Message-ID: On Tue, 3 Jan 2023 12:36:17 GMT, Michael McMahon wrote: > Happy new year! Thanks Alan for checking this. Can I get a more formal review? I didn't get time to study the test changes but I see Michael did, so I think you are good to go. ------------- PR: https://git.openjdk.org/jdk/pull/11638 From alanb at openjdk.org Thu Jan 5 17:46:36 2023 From: alanb at openjdk.org (Alan Bateman) Date: Thu, 5 Jan 2023 17:46:36 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup Message-ID: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. There are a couple of random cleanup/formatting nits in this patch. ------------- Commit messages: - Initial commit Changes: https://git.openjdk.org/jdk/pull/11863/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=11863&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8278326 Stats: 909 lines in 5 files changed: 678 ins; 89 del; 142 mod Patch: https://git.openjdk.org/jdk/pull/11863.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11863/head:pull/11863 PR: https://git.openjdk.org/jdk/pull/11863 From duke at openjdk.org Thu Jan 5 22:18:30 2023 From: duke at openjdk.org (Justin Lu) Date: Thu, 5 Jan 2023 22:18:30 GMT Subject: RFR: 8299499: Usage of constructors of primitive wrapper classes should be avoided in java.net API docs Message-ID: Replacing deprecated constructors of primitive wrapper classes. Used valueOf() method as replacement. Alternatively, auto boxing could have been used here as well. It would be beneficial to set a precedent for the other related doc bugs. ------------- Commit messages: - Replace constructors with valueOf() Changes: https://git.openjdk.org/jdk/pull/11866/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=11866&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8299499 Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/11866.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11866/head:pull/11866 PR: https://git.openjdk.org/jdk/pull/11866 From duke at openjdk.org Thu Jan 5 22:18:31 2023 From: duke at openjdk.org (Justin Lu) Date: Thu, 5 Jan 2023 22:18:31 GMT Subject: RFR: 8299499: Usage of constructors of primitive wrapper classes should be avoided in java.net API docs In-Reply-To: References: Message-ID: On Thu, 5 Jan 2023 19:09:29 GMT, Justin Lu wrote: > Replacing deprecated constructors of primitive wrapper classes. Used valueOf() method as replacement. > > Alternatively, auto boxing could have been used here as well. It would be beneficial to set a precedent for the other related doc bugs. I chose valueOf() because I thought it provided more clarity from a documentation standpoint. Open to any suggestions. ------------- PR: https://git.openjdk.org/jdk/pull/11866 From naoto at openjdk.org Fri Jan 6 00:11:51 2023 From: naoto at openjdk.org (Naoto Sato) Date: Fri, 6 Jan 2023 00:11:51 GMT Subject: RFR: 8299499: Usage of constructors of primitive wrapper classes should be avoided in java.net API docs In-Reply-To: References: Message-ID: On Thu, 5 Jan 2023 19:09:29 GMT, Justin Lu wrote: > Replacing deprecated constructors of primitive wrapper classes. Used valueOf() method as replacement. > > Alternatively, auto boxing could have been used here as well. It would be beneficial to set a precedent for the other related doc bugs. LGTM. Please modify the copyright year ------------- Marked as reviewed by naoto (Reviewer). PR: https://git.openjdk.org/jdk/pull/11866 From duke at openjdk.org Fri Jan 6 00:27:31 2023 From: duke at openjdk.org (Justin Lu) Date: Fri, 6 Jan 2023 00:27:31 GMT Subject: RFR: 8299499: Usage of constructors of primitive wrapper classes should be avoided in java.net API docs [v2] In-Reply-To: References: Message-ID: > Replacing deprecated constructors of primitive wrapper classes. Used valueOf() method as replacement. > > Alternatively, auto boxing could have been used here as well. It would be beneficial to set a precedent for the other related doc bugs. Justin Lu has updated the pull request incrementally with two additional commits since the last revision: - Actually fix copyright year - Copyright year ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11866/files - new: https://git.openjdk.org/jdk/pull/11866/files/304a83c4..b87b9e97 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11866&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11866&range=00-01 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/11866.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11866/head:pull/11866 PR: https://git.openjdk.org/jdk/pull/11866 From naoto at openjdk.org Fri Jan 6 00:27:31 2023 From: naoto at openjdk.org (Naoto Sato) Date: Fri, 6 Jan 2023 00:27:31 GMT Subject: RFR: 8299499: Usage of constructors of primitive wrapper classes should be avoided in java.net API docs [v2] In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 00:22:42 GMT, Justin Lu wrote: >> Replacing deprecated constructors of primitive wrapper classes. Used valueOf() method as replacement. >> >> Alternatively, auto boxing could have been used here as well. It would be beneficial to set a precedent for the other related doc bugs. > > Justin Lu has updated the pull request incrementally with two additional commits since the last revision: > > - Actually fix copyright year > - Copyright year Seems that you modified a different file? ------------- Changes requested by naoto (Reviewer). PR: https://git.openjdk.org/jdk/pull/11866 From duke at openjdk.org Fri Jan 6 00:27:31 2023 From: duke at openjdk.org (Justin Lu) Date: Fri, 6 Jan 2023 00:27:31 GMT Subject: RFR: 8299499: Usage of constructors of primitive wrapper classes should be avoided in java.net API docs [v2] In-Reply-To: References: Message-ID: <8ADXOpjZR5vmrirV39R90_r9Q7mpX5SpdyhTnrpB_Hs=.521e33ac-bd8f-4a14-84c8-b4669b4055df@github.com> On Fri, 6 Jan 2023 00:18:38 GMT, Naoto Sato wrote: > Seems that you modified a different file? Yes I did, ?. Thanks for catching that, fixed it. ------------- PR: https://git.openjdk.org/jdk/pull/11866 From naoto at openjdk.org Fri Jan 6 00:30:49 2023 From: naoto at openjdk.org (Naoto Sato) Date: Fri, 6 Jan 2023 00:30:49 GMT Subject: RFR: 8299499: Usage of constructors of primitive wrapper classes should be avoided in java.net API docs [v2] In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 00:27:31 GMT, Justin Lu wrote: >> Replacing deprecated constructors of primitive wrapper classes. Used valueOf() method as replacement. >> >> Alternatively, auto boxing could have been used here as well. It would be beneficial to set a precedent for the other related doc bugs. > > Justin Lu has updated the pull request incrementally with two additional commits since the last revision: > > - Actually fix copyright year > - Copyright year Marked as reviewed by naoto (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/11866 From jpai at openjdk.org Fri Jan 6 00:57:49 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Fri, 6 Jan 2023 00:57:49 GMT Subject: RFR: 8299499: Usage of constructors of primitive wrapper classes should be avoided in java.net API docs [v2] In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 00:27:31 GMT, Justin Lu wrote: >> Replacing deprecated constructors of primitive wrapper classes. Used valueOf() method as replacement. >> >> Alternatively, auto boxing could have been used here as well. It would be beneficial to set a precedent for the other related doc bugs. > > Justin Lu has updated the pull request incrementally with two additional commits since the last revision: > > - Actually fix copyright year > - Copyright year Marked as reviewed by jpai (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/11866 From jpai at openjdk.org Fri Jan 6 00:57:51 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Fri, 6 Jan 2023 00:57:51 GMT Subject: RFR: 8299499: Usage of constructors of primitive wrapper classes should be avoided in java.net API docs In-Reply-To: References: Message-ID: On Thu, 5 Jan 2023 19:33:39 GMT, Justin Lu wrote: > I chose valueOf() because I thought it provided more clarity from a documentation standpoint. I agree. This looks good to me. ------------- PR: https://git.openjdk.org/jdk/pull/11866 From duke at openjdk.org Fri Jan 6 02:45:18 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 6 Jan 2023 02:45:18 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor Message-ID: This PR adds a new lint warning category `this-escape`. It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) * Some constructor `B()` of `B` invokes `A()` as its superclass constructor * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. **Patch Navigation Guide** * Non-trivial compiler changes: * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` * Javadoc additions of `@implNote`: * `src/java.base/share/classes/java/io/PipedReader.java` * `src/java.base/share/classes/java/io/PipedWriter.java` * `src/java.base/share/classes/java/lang/Throwable.java` * `src/java.base/share/classes/java/util/ArrayDeque.java` * `src/java.base/share/classes/java/util/EnumMap.java` * `src/java.base/share/classes/java/util/HashSet.java` * `src/java.base/share/classes/java/util/Hashtable.java` * `src/java.base/share/classes/java/util/LinkedList.java` * `src/java.base/share/classes/java/util/TreeMap.java` * `src/java.base/share/classes/java/util/TreeSet.java` * New unit tests * `test/langtools/tools/javac/warnings/ThisEscape/*.java` * **Everything else** is just adding `@SuppressWarnings("this-escape")` ------------- Commit messages: - Remove trailing whitespace. - Some documentation tweaks. - Treat method references like the equivalent lambda. - Fix bug where initializers could generate duplicate warnings. - Javadoc fix. - Add ThisEscape.html doc note and link the new @implNote's to it. - Add more @SuppressWarnings("this-escape") annotations. - Add more @SuppressWarnings("this-escape") annotations. - Add more @SuppressWarnings("this-escape") annotations. - Add more @SuppressWarnings("this-escape") annotations. - ... and 38 more: https://git.openjdk.org/jdk/compare/c6588d5b...9c162283 Changes: https://git.openjdk.org/jdk/pull/11874/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8015831 Stats: 4326 lines in 1285 files changed: 4259 ins; 3 del; 64 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From dholmes at openjdk.org Fri Jan 6 04:51:00 2023 From: dholmes at openjdk.org (David Holmes) Date: Fri, 6 Jan 2023 04:51:00 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 02:20:53 GMT, Archie L. Cobbs wrote: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Hi Archie, The associated JBS issue has been dormant for 6+ years and this is a very intrusive change affecting many, many files. Has the resurrection of this project previously been discussed somewhere? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From alanb at openjdk.org Fri Jan 6 07:53:54 2023 From: alanb at openjdk.org (Alan Bateman) Date: Fri, 6 Jan 2023 07:53:54 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 02:20:53 GMT, Archie L. Cobbs wrote: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` This looks like a very useful lint warning to have but this PR is unwieldy. If you haven't done so already then you probably should socialize on compiler-dev and get agreement on the semantics and other details. I think you will also need to separate the addition of the lint warning from the changes to the wider JDK. It might be okay to add the feature but have it disabled for the JDK build initially. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 6 14:51:54 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 6 Jan 2023 14:51:54 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 04:48:27 GMT, David Holmes wrote: > The associated JBS issue has been dormant for 6+ years and this is a very intrusive change affecting many, many files. Has the resurrection of this project previously been discussed somewhere? Hi @dholmes-ora, The work to add this warning has been guided by @briangoetz in discussions on the amber-dev mailing list. See that thread for how we came up with the current design, underlying motivation, etc. Regarding intrusiveness (assuming you're referring simply to the number of files touched), as mentioned this was one of two options. The other option would be to patch to about ~30 `Java.gmk` files in `make/modules` to exclude `this-escape` from `-Xlint` during the various module builds. Going this route is fine with me, but it has the downside that any new code being developed would not benefit from the new warning. This was in fact my original approach (and it was a lot easier :) but Brian rightly pointed out that adding `@SuppressWarnings` annotations was the the safer (i.e, more conservative) approach. > If you haven't done so already then you probably should socialize on compiler-dev and get agreement on the semantics and other details. Hi @AlanBateman, As mentioned this has been under discussion on amber-dev for a while. Happy to continue that discussion here as well. > I think you will also need to separate the addition of the lint warning from the changes to the wider JDK. It might be okay to add the feature but have it disabled for the JDK build initially. Sounds reasonable... so I take it you would also be in favor of patching `make/modules` instead of adding `@SuppressWarnings` annotations everywhere... is that correct? If this is generally agreed as a better route then let me know and I'll update the patch. Thanks for both of your comments. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From alanb at openjdk.org Fri Jan 6 15:41:16 2023 From: alanb at openjdk.org (Alan Bateman) Date: Fri, 6 Jan 2023 15:41:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 14:49:16 GMT, Archie L. Cobbs wrote: > Sounds reasonable... so I take it you would also be in favor of patching `make/modules` instead of adding `@SuppressWarnings` annotations everywhere... is that correct? > > If this is generally agreed as a better route then let me know and I'll update the patch. Yes, I think that would be better. It would remove most of the noise, 1200+ files, and 10+ mailing lists from this PR. I assume there will be at least some iteration on compiler-dev about the details and changes to javac. Once you get to the JDK changes then I suspect that some areas may want to fix issues rather than adding SW. Sadly, I see a few examples in your list where there have been attempts to avoid leaking "this" but where we backed away out of concern that 3rd party code was extending some class and overriding a method known to be invoked by the constructor. Also we have places that register themselves to cleaners. I suspect some of the suggestions to document leaking this in implNotes will need discussion too because they amount to documenting "hooks" that people will rely on, e.g. documenting in ArrayDeque that its constructor invokes addList could be read as an invite to override it. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Fri Jan 6 15:57:50 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 6 Jan 2023 15:57:50 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 15:38:31 GMT, Alan Bateman wrote: >>> The associated JBS issue has been dormant for 6+ years and this is a very intrusive change affecting many, many files. Has the resurrection of this project previously been discussed somewhere? >> >> Hi @dholmes-ora, >> >> The work to add this warning has been guided by @briangoetz in discussions on the amber-dev mailing list. See that thread for how we came up with the current design, underlying motivation, etc. >> >> Regarding intrusiveness (assuming you're referring simply to the number of files touched), as mentioned this was one of two options. The other option would be to patch to about ~30 `Java.gmk` files in `make/modules` to exclude `this-escape` from `-Xlint` during the various module builds. >> >> Going this route is fine with me, but it has the downside that any new code being developed would not benefit from the new warning. This was in fact my original approach (and it was a lot easier :) but Brian rightly pointed out that adding `@SuppressWarnings` annotations was the the safer (i.e, more conservative) approach. >> >>> If you haven't done so already then you probably should socialize on compiler-dev and get agreement on the semantics and other details. >> >> Hi @AlanBateman, >> >> As mentioned this has been under discussion on amber-dev for a while. Happy to continue that discussion here as well. >> >>> I think you will also need to separate the addition of the lint warning from the changes to the wider JDK. It might be okay to add the feature but have it disabled for the JDK build initially. >> >> Sounds reasonable... so I take it you would also be in favor of patching `make/modules` instead of adding `@SuppressWarnings` annotations everywhere... is that correct? >> >> If this is generally agreed as a better route then let me know and I'll update the patch. >> >> Thanks for both of your comments. > >> Sounds reasonable... so I take it you would also be in favor of patching `make/modules` instead of adding `@SuppressWarnings` annotations everywhere... is that correct? >> >> If this is generally agreed as a better route then let me know and I'll update the patch. > > Yes, I think that would be better. It would remove most of the noise, 1200+ files, and 10+ mailing lists from this PR. I assume there will be at least some iteration on compiler-dev about the details and changes to javac. Once you get to the JDK changes then I suspect that some areas may want to fix issues rather than adding SW. Sadly, I see a few examples in your list where there have been attempts to avoid leaking "this" but where we backed away out of concern that 3rd party code was extending some class and overriding a method known to be invoked by the constructor. Also we have places that register themselves to cleaners. I suspect some of the suggestions to document leaking this in implNotes will need discussion too because they amount to documenting "hooks" that people will rely on, e.g. documenting in ArrayDeque that its constructor invokes addList could be read as an invite to override it. I agree with @AlanBateman. When we introduced similar warnings in the past, we have enabled support in javac (with some test) in a separate PR, and then followed up with small dedicated PR for each of the various areas (enabling new warnings one by one). See this great umbrella JBS issue (created by @asotona) which has details on all the issues that were filed when we added an extra Lint warning for lossy conversions: https://bugs.openjdk.org/browse/JDK-8286374 They all refer to this: https://bugs.openjdk.org/browse/JDK-8244681 Which was submitted as a separate javac-only PR: https://github.com/openjdk/jdk/pull/8599 ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 6 23:13:09 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 6 Jan 2023 23:13:09 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v2] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: - Update copyright year for newly added files to 2023. - Suppress "this-escape" warnings using build flags instead of @SuppressAnnotations annotations. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/9c162283..f667cd56 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=00-01 Stats: 1935 lines in 1303 files changed: 60 ins; 1770 del; 105 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 6 23:13:09 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 6 Jan 2023 23:13:09 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 15:38:31 GMT, Alan Bateman wrote: >>> The associated JBS issue has been dormant for 6+ years and this is a very intrusive change affecting many, many files. Has the resurrection of this project previously been discussed somewhere? >> >> Hi @dholmes-ora, >> >> The work to add this warning has been guided by @briangoetz in discussions on the amber-dev mailing list. See that thread for how we came up with the current design, underlying motivation, etc. >> >> Regarding intrusiveness (assuming you're referring simply to the number of files touched), as mentioned this was one of two options. The other option would be to patch to about ~30 `Java.gmk` files in `make/modules` to exclude `this-escape` from `-Xlint` during the various module builds. >> >> Going this route is fine with me, but it has the downside that any new code being developed would not benefit from the new warning. This was in fact my original approach (and it was a lot easier :) but Brian rightly pointed out that adding `@SuppressWarnings` annotations was the the safer (i.e, more conservative) approach. >> >>> If you haven't done so already then you probably should socialize on compiler-dev and get agreement on the semantics and other details. >> >> Hi @AlanBateman, >> >> As mentioned this has been under discussion on amber-dev for a while. Happy to continue that discussion here as well. >> >>> I think you will also need to separate the addition of the lint warning from the changes to the wider JDK. It might be okay to add the feature but have it disabled for the JDK build initially. >> >> Sounds reasonable... so I take it you would also be in favor of patching `make/modules` instead of adding `@SuppressWarnings` annotations everywhere... is that correct? >> >> If this is generally agreed as a better route then let me know and I'll update the patch. >> >> Thanks for both of your comments. > >> Sounds reasonable... so I take it you would also be in favor of patching `make/modules` instead of adding `@SuppressWarnings` annotations everywhere... is that correct? >> >> If this is generally agreed as a better route then let me know and I'll update the patch. > > Yes, I think that would be better. It would remove most of the noise, 1200+ files, and 10+ mailing lists from this PR. I assume there will be at least some iteration on compiler-dev about the details and changes to javac. Once you get to the JDK changes then I suspect that some areas may want to fix issues rather than adding SW. Sadly, I see a few examples in your list where there have been attempts to avoid leaking "this" but where we backed away out of concern that 3rd party code was extending some class and overriding a method known to be invoked by the constructor. Also we have places that register themselves to cleaners. I suspect some of the suggestions to document leaking this in implNotes will need discussion too because they amount to documenting "hooks" that people will rely on, e.g. documenting in ArrayDeque that its constructor invokes addList could be read as an invite to override it. Hi @AlanBateman, OK that sounds like a plan. I've pushed a new commit to the `ThisEscape` branch that removes all the`@SuppressWarnings` annotations and replaces them with adjustments to build flags. I've moved the `@SuppressWarnings` annotations onto a new branch `ThisEscapeAnnotations`. This is just for future reference in case somebody wants to add them back someday and doesn't want to start from scratch. > I suspect some of the suggestions to document leaking this in implNotes will need discussion too because they amount to documenting "hooks" that people will rely on, e.g. documenting in ArrayDeque that its constructor invokes addList could be read as an invite to override it. Hmm. Hasn't that horse already left the barn? You kind of implied that when you said: > I see a few examples in your list where there have been attempts to avoid leaking "this" but where we backed away out of concern that 3rd party code was extending some class and overriding a method known to be invoked by the constructor. In other words, it doesn't sound like changing the behavior of these constructors is viable option at this point. And if that's the case, we might as well document and warn about the current behavior. Of course I'd love to be wrong... in which case, we can fix these constructors. Or, the third option - just do nothing yet. That would mean removing the warnings, which is fine. But then the `ThisEscape.html` document is orphaned. What should we do with it? I can remove it, just leave it there, or put it somewhere else (where?). It seems like having some documentation of the meaning of "this escape" would be helpful, because it's a subtle concept and there are multiple ways to define "escape". Thanks. @mcimadamore thanks for the bugs suggestion, I'll put that on the to-do list. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Sat Jan 7 02:21:57 2023 From: duke at openjdk.org (Justin Lu) Date: Sat, 7 Jan 2023 02:21:57 GMT Subject: Integrated: 8299499: Usage of constructors of primitive wrapper classes should be avoided in java.net API docs In-Reply-To: References: Message-ID: On Thu, 5 Jan 2023 19:09:29 GMT, Justin Lu wrote: > Replacing deprecated constructors of primitive wrapper classes. Used valueOf() method as replacement. > > Alternatively, auto boxing could have been used here as well. It would be beneficial to set a precedent for the other related doc bugs. This pull request has now been integrated. Changeset: 63cf4aa0 Author: Justin Lu Committer: Jaikiran Pai URL: https://git.openjdk.org/jdk/commit/63cf4aa0c897406fc9370a8e05cb035caafc5d69 Stats: 3 lines in 1 file changed: 0 ins; 0 del; 3 mod 8299499: Usage of constructors of primitive wrapper classes should be avoided in java.net API docs Reviewed-by: naoto, jpai ------------- PR: https://git.openjdk.org/jdk/pull/11866 From duke at openjdk.org Sat Jan 7 16:24:56 2023 From: duke at openjdk.org (ExE Boss) Date: Sat, 7 Jan 2023 16:24:56 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v2] In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 23:13:09 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Update copyright year for newly added files to 2023. > - Suppress "this-escape" warnings using build flags instead of @SuppressAnnotations annotations. src/java.base/share/classes/java/lang/AssertionError.java line 75: > 73: */ > 74: @SuppressWarnings("this-escape") > 75: public AssertionError(Object detailMessage) { The?Javadoc of?this?constructor should?probably?mention that?it?calls `initCause(?)` when?`detailMessage` is?a?`Throwable`. src/java.base/share/classes/java/lang/BootstrapMethodError.java line 77: > 75: * Constructs a {@code BootstrapMethodError} with the specified > 76: * cause. > 77: * Suggestion: * * @implNote This constructor invokes {@link #initCause initCause()}; see * This Escape. * src/java.base/share/classes/java/lang/ExceptionInInitializerError.java line 54: > 52: * throwable object. > 53: * A detail message is a String that describes this particular exception. > 54: */ Suggestion: * * @implNote This constructor invokes {@link #initCause initCause()}; see * This Escape. */ ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Sat Jan 7 16:58:58 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Sat, 7 Jan 2023 16:58:58 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v3] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Add a few more Javadoc warnings for 'this' escape via initCause(). ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/f667cd56..398737fa Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=01-02 Stats: 9 lines in 3 files changed: 9 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From alanb at openjdk.org Sat Jan 7 18:05:50 2023 From: alanb at openjdk.org (Alan Bateman) Date: Sat, 7 Jan 2023 18:05:50 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Fri, 6 Jan 2023 23:08:27 GMT, Archie L. Cobbs wrote: > I've moved the `@SuppressWarnings` annotations onto a new branch `ThisEscapeAnnotations`. This is just for future reference in case somebody wants to add them back someday and doesn't want to start from scratch. > > > I suspect some of the suggestions to document leaking this in implNotes will need discussion too because they amount to documenting "hooks" that people will rely on, e.g. documenting in ArrayDeque that its constructor invokes addList could be read as an invite to override it. > > Hmm. Hasn't that horse already left the barn? You kind of implied that when you said: > > > I see a few examples in your list where there have been attempts to avoid leaking "this" but where we backed away out of concern that 3rd party code was extending some class and overriding a method known to be invoked by the constructor. > > In other words, it doesn't sound like changing the behavior of these constructors is viable option at this point. And if that's the case, we might as well document and warn about the current behavior. > > Of course I'd love to be wrong... in which case, we can fix these constructors. I hope at least some of these can be fixed as leaking a part initialized object to an untrusted subclass or some other code is problematic in many ways. Skimming through the original list, then some of these may be accidental and some may be fixable without any compatibility concerns, esp. in the JDK internal classes. Yes, some horses have left the barn. A horse that got out a long time ago is j.net.ServerSocket where 3 of its constructors call an overridable bind method. Recent re-implementation would have fixed this but there were concerns that subclasses may be relying on this long standing undocumented behavior. There are other cases in the list where the leaking may be necessary part of the contract for subclasses. So it will probably require working through them on a case by case basis. I don't think the implementation notes should be included as part of the adding the lint warning as I think it creates an attractive nuisance. Developers reading these implementation notes may c reate code that depends on these "hooks" and it will make it very hard for the JDK to ever change the behavior. Where the leaking is a necessary part of the contract for subclassing then it may be that it has to be documented as normative text rather than an implementation note. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Sat Jan 7 19:52:49 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Sat, 7 Jan 2023 19:52:49 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor In-Reply-To: References: Message-ID: On Sat, 7 Jan 2023 18:03:04 GMT, Alan Bateman wrote: > I don't think the implementation notes should be included as part of the adding the lint warning as I think it creates an attractive nuisance. I agree with you - not only for that reason, but also because as others have pointed out the addition of the warning is really a separate task from the evaluation and triage of any existing leaks. Moreover, this latter task is really multiple separate tasks that belong to the various module/functional groups. I'll remove all the Javadoc `@implNote`'s from the patch, and `src/java.base/share/classes/java/lang/doc-files/ThisEscape.html` as well - it will still be available in the git history if someone comes up with a better home for it. This will also further reduce the number of labels and therefore required reviewers. Thanks. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Sat Jan 7 19:59:59 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Sat, 7 Jan 2023 19:59:59 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v4] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Remove Javadoc @implNotes; plan to triage the various existing leaks separately. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/398737fa..537b3e3c Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=02-03 Stats: 255 lines in 29 files changed: 0 ins; 251 del; 4 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Sat Jan 7 21:08:07 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Sat, 7 Jan 2023 21:08:07 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: Message-ID: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Fix incorrect @bug numbers in unit tests. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/537b3e3c..7e2fdb07 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=03-04 Stats: 15 lines in 15 files changed: 0 ins; 0 del; 15 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From aturbanov at openjdk.org Sun Jan 8 19:29:51 2023 From: aturbanov at openjdk.org (Andrey Turbanov) Date: Sun, 8 Jan 2023 19:29:51 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Thu, 5 Jan 2023 14:39:28 GMT, Alan Bateman wrote: > java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. > > Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. > > There are a couple of random cleanup/formatting nits in this patch. src/java.base/share/classes/java/net/Socket.java line 1311: > 1309: * @since 1.4 > 1310: */ > 1311: public void sendUrgentData(int data) throws IOException { Suggestion: public void sendUrgentData(int data) throws IOException { ------------- PR: https://git.openjdk.org/jdk/pull/11863 From jpai at openjdk.org Mon Jan 9 06:33:52 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Mon, 9 Jan 2023 06:33:52 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: <7a8Qi-oYQFArhs_kYXq-IEJIBtwW1veExFZ3Ud38QjE=.0aa9da9c-0f11-4671-a88e-1629ceb38ec8@github.com> On Thu, 5 Jan 2023 14:39:28 GMT, Alan Bateman wrote: > java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. > > Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. > > There are a couple of random cleanup/formatting nits in this patch. src/java.base/share/classes/java/net/ServerSocket.java line 286: > 284: > 285: /** > 286: * Create a SocketImpl for a server socket. The SocketImpl s created Typo - I think this should have been "The SocketImpl is ...." ------------- PR: https://git.openjdk.org/jdk/pull/11863 From dholmes at openjdk.org Mon Jan 9 06:39:52 2023 From: dholmes at openjdk.org (David Holmes) Date: Mon, 9 Jan 2023 06:39:52 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Sat, 7 Jan 2023 21:08:07 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: > > Fix incorrect @bug numbers in unit tests. All your new files need a copyright and GPL header. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From djelinski at openjdk.org Mon Jan 9 07:45:01 2023 From: djelinski at openjdk.org (Daniel =?UTF-8?B?SmVsacWEc2tp?=) Date: Mon, 9 Jan 2023 07:45:01 GMT Subject: Integrated: 6914801: IPv6 unavailable if stdin is a socket In-Reply-To: References: Message-ID: On Mon, 12 Dec 2022 20:30:05 GMT, Daniel Jeli?ski wrote: > This patch reenables IPv6 stack when stdin is an IPv4 socket. > > The code that blocked IPv6 was introduced in JDK-4673940 back when JDK could only operate with either IPv4 or IPv6 sockets, and was using `IPv6_available` to determine which socket type was in use. Now that JDK is able to operate with both IPv4 and IPv6 sockets at the same time, the check for IPv4 stdin is no longer relevant. > > Included test passes with the changes applied, fails without them. Other tier1-3 tests also pass. This pull request has now been integrated. Changeset: 8d17d1ee Author: Daniel Jeli?ski URL: https://git.openjdk.org/jdk/commit/8d17d1ee6f08ee90771d469182aaaaa7c23971fd Stats: 199 lines in 7 files changed: 161 ins; 22 del; 16 mod 6914801: IPv6 unavailable if stdin is a socket Reviewed-by: michaelm ------------- PR: https://git.openjdk.org/jdk/pull/11638 From michaelm at openjdk.org Mon Jan 9 10:03:53 2023 From: michaelm at openjdk.org (Michael McMahon) Date: Mon, 9 Jan 2023 10:03:53 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Thu, 5 Jan 2023 14:39:28 GMT, Alan Bateman wrote: > java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. > > Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. > > There are a couple of random cleanup/formatting nits in this patch. src/java.base/share/classes/java/net/ServerSocket.java line 98: > 96: this.impl = Objects.requireNonNull(impl); > 97: } > 98: What's the reason for adding this new private constructor? I don't see what the problem with the original single arg one is. `checkPermission` could be declared to return void instead of Void though. ------------- PR: https://git.openjdk.org/jdk/pull/11863 From alanb at openjdk.org Mon Jan 9 10:30:53 2023 From: alanb at openjdk.org (Alan Bateman) Date: Mon, 9 Jan 2023 10:30:53 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Mon, 9 Jan 2023 10:01:05 GMT, Michael McMahon wrote: >> java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. >> >> Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. >> >> There are a couple of random cleanup/formatting nits in this patch. > > src/java.base/share/classes/java/net/ServerSocket.java line 98: > >> 96: this.impl = Objects.requireNonNull(impl); >> 97: } >> 98: > > What's the reason for adding this new private constructor? I don't see what the problem with the original single arg one is. `checkPermission` could be declared to return void instead of Void though. Permission checks in constructors of non-final classes are problematic when the subclass has a finalizer. It's fixed here with the same idiom that we use in other places. The return is used by as parameter so it has to be Void. ------------- PR: https://git.openjdk.org/jdk/pull/11863 From jpai at openjdk.org Mon Jan 9 10:37:51 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Mon, 9 Jan 2023 10:37:51 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Thu, 5 Jan 2023 14:39:28 GMT, Alan Bateman wrote: > java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. > > Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. > > There are a couple of random cleanup/formatting nits in this patch. src/java.base/share/classes/java/net/Socket.java line 636: > 634: if (previous != null) { > 635: in = null; > 636: out = null; Hello Alan, I haven't fully grasped this part of the change yet. I see that we now null out these input and outputstreams of the `Socket` instance. If an inputstream was handed out by this `Socket` instance (through a call to `Socket.getInputStream()`) and if the application code calls `InputStream.close()` after this `setConnectedImpl` has been called, then that call to `close()` can lead to closing this newly set `SocketImpl`. Is that OK? Or should that close on the "old" InputStream end up being a no-op? Like I noted, I still haven't fully wrapped my head around this `setConnectedImpl` so maybe this combination of calls is not be possible/practical? ------------- PR: https://git.openjdk.org/jdk/pull/11863 From michaelm at openjdk.org Mon Jan 9 11:03:53 2023 From: michaelm at openjdk.org (Michael McMahon) Date: Mon, 9 Jan 2023 11:03:53 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Mon, 9 Jan 2023 10:28:33 GMT, Alan Bateman wrote: >> src/java.base/share/classes/java/net/ServerSocket.java line 98: >> >>> 96: this.impl = Objects.requireNonNull(impl); >>> 97: } >>> 98: >> >> What's the reason for adding this new private constructor? I don't see what the problem with the original single arg one is. `checkPermission` could be declared to return void instead of Void though. > > Permission checks in constructors of non-final classes are problematic when the subclass has a finalizer. It's fixed here with the same idiom that we use in other places. The return is used by as parameter so it has to be Void. Okay, it just seemed odd that `checkPermission` already had return type Void as if a change like this was started but not completed. ------------- PR: https://git.openjdk.org/jdk/pull/11863 From alanb at openjdk.org Mon Jan 9 12:19:52 2023 From: alanb at openjdk.org (Alan Bateman) Date: Mon, 9 Jan 2023 12:19:52 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Mon, 9 Jan 2023 11:00:47 GMT, Michael McMahon wrote: >> Permission checks in constructors of non-final classes are problematic when the subclass has a finalizer. It's fixed here with the same idiom that we use in other places. The return is used by as parameter so it has to be Void. > > Okay, it just seemed odd that `checkPermission` already had return type Void as if a change like this was started but not completed. Yeah, this idiom might be confusing when you see it first time. The checkPermission method could return another type, we've just used Void to make it a bit clearer that the parameter is not used. ------------- PR: https://git.openjdk.org/jdk/pull/11863 From alanb at openjdk.org Mon Jan 9 12:19:54 2023 From: alanb at openjdk.org (Alan Bateman) Date: Mon, 9 Jan 2023 12:19:54 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Mon, 9 Jan 2023 10:35:18 GMT, Jaikiran Pai wrote: >> java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. >> >> Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. >> >> There are a couple of random cleanup/formatting nits in this patch. > > src/java.base/share/classes/java/net/Socket.java line 636: > >> 634: if (previous != null) { >> 635: in = null; >> 636: out = null; > > Hello Alan, I haven't fully grasped this part of the change yet. I see that we now null out these input and outputstreams of the `Socket` instance. If an inputstream was handed out by this `Socket` instance (through a call to `Socket.getInputStream()`) and if the application code calls `InputStream.close()` after this `setConnectedImpl` has been called, then that call to `close()` can lead to closing this newly set `SocketImpl`. Is that OK? Or should that close on the "old" InputStream end up being a no-op? Like I noted, I still haven't fully wrapped my head around this `setConnectedImpl` so maybe this combination of calls is not possible/practical? ServerSocket.implAccept is intended to be called with a newly created, and unbound, Socket. We looked at this topic in JDK 13 (see JDK-8225431 and related issues) and decided the behavior is unspecified for silly/broken cases where it is called with a Socket in any other state. It should probably have been specified to throw ISE when introduced in JDK 1.1 but we decided there wasn't enough motive to try to fix the spec for that. This PR touches this area again because it interacts with Socket.close. So the question is what is the JDK behavior when calling implAccept with a connected Socket. A Socket can't have two connections at the same time. The JDK behavior is to attach the SocketImpl for the newly accepted connection to the Socket. This breaks the association from the Socket to the previous SocketImpl. This PR doesn't change that. It does re-visit the question as to what to do with the now orphaned SocketImpl. Should it be discarded, in which case it may be a resource leak, or should it be closed? The former seems preferable, in which case the read/write methods of streams handed out before calling implAccept will throw IOException. Your question is what happens if the input or output stream close method is called? The spec is that the close method closes the Socket so I've left this as is, it's not changed in this PR. The only real change here is that calling getInputStream/getOutputStream after accepting the new connection will return streams to the newly accepted connect ion. That seems the most sensible thing to do for this crazy case. ------------- PR: https://git.openjdk.org/jdk/pull/11863 From duke at openjdk.org Mon Jan 9 14:03:54 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 9 Jan 2023 14:03:54 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Mon, 9 Jan 2023 06:37:22 GMT, David Holmes wrote: > All your new files need a copyright and GPL header. Sorry if I'm being blind but I'm not seeing it. Which file(s) are you referring to? The `@test /nodynamiccopyright/` files don't get one per [this](https://openjdk.org/groups/compiler/tests.html#gold). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From jpai at openjdk.org Tue Jan 10 13:42:54 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Tue, 10 Jan 2023 13:42:54 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: <61qCV0yrvMl0uJlQFfUnoGI8oKH7RjyoQvdOj7FuOv8=.50a6aa91-77fe-4e46-bd3c-166f0ef5eedf@github.com> On Mon, 9 Jan 2023 12:15:39 GMT, Alan Bateman wrote: >> src/java.base/share/classes/java/net/Socket.java line 636: >> >>> 634: if (previous != null) { >>> 635: in = null; >>> 636: out = null; >> >> Hello Alan, I haven't fully grasped this part of the change yet. I see that we now null out these input and outputstreams of the `Socket` instance. If an inputstream was handed out by this `Socket` instance (through a call to `Socket.getInputStream()`) and if the application code calls `InputStream.close()` after this `setConnectedImpl` has been called, then that call to `close()` can lead to closing this newly set `SocketImpl`. Is that OK? Or should that close on the "old" InputStream end up being a no-op? Like I noted, I still haven't fully wrapped my head around this `setConnectedImpl` so maybe this combination of calls is not possible/practical? > > ServerSocket.implAccept is intended to be called with a newly created, and unbound, Socket. We looked at this topic in JDK 13 (see JDK-8225431 and related issues) and decided the behavior is unspecified for silly/broken cases where it is called with a Socket in any other state. It should probably have been specified to throw ISE when introduced in JDK 1.1 but we decided there wasn't enough motive to try to fix the spec for that. This PR touches this area again because it interacts with Socket.close. > > So the question is what is the JDK behavior when calling implAccept with a connected Socket. A Socket can't have two connections at the same time. The JDK behavior is to attach the SocketImpl for the newly accepted connection to the Socket. This breaks the association from the Socket to the previous SocketImpl. This PR doesn't change that. It does re-visit the question as to what to do with the now orphaned SocketImpl. Should it be discarded, in which case it may be a resource leak, or should it be closed? The former seems preferable, in which case the read/write methods of streams handed out before calling implAccept will throw IOException. Your question is what happens if the input or output stream close method is called? The spec is that the close method closes the Socket so I've left this as is, it's not changed in this PR. The only real change here is that calling getInputStream/getOutputStream after accepting the new connection will return streams to the newly accepted conne ction. That seems the most sensible thing to do for this crazy case. Thank you for that detailed explanation, Alan. That helped. > Should it be discarded, in which case it may be a resource leak, or should it be closed? The former seems preferable, in which case the read/write methods of streams handed out before calling implAccept will throw IOException. I'm guessing that is a typo and you actually mean "The latter seems preferable ..."? The implementation in this PR does the latter and closes the previous orphaned SocketImpl and I think that's the right thing to do. ------------- PR: https://git.openjdk.org/jdk/pull/11863 From jpai at openjdk.org Tue Jan 10 13:42:57 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Tue, 10 Jan 2023 13:42:57 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Thu, 5 Jan 2023 14:39:28 GMT, Alan Bateman wrote: > java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. > > Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. > > There are a couple of random cleanup/formatting nits in this patch. test/jdk/java/net/ServerSocket/ImplAccept.java line 247: > 245: } > 246: > 247: // call getSocket to get the value of the SO_REUSEADDR socket option This appears to be a typo. I think this should have been "call getOption..." test/jdk/java/net/ServerSocket/ImplAccept.java line 251: > 249: m.setAccessible(true); > 250: try { > 251: m.invoke(si, StandardSocketOptions.SO_REUSEADDR); If I understand this correctly, we are calling this method just to have the underlying native call to go through and the actual choice of the option name (in this case the SO_REUSEADDR) isn't of any importance? ------------- PR: https://git.openjdk.org/jdk/pull/11863 From jpai at openjdk.org Tue Jan 10 13:50:55 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Tue, 10 Jan 2023 13:50:55 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Thu, 5 Jan 2023 14:39:28 GMT, Alan Bateman wrote: > java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. > > Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. > > There are a couple of random cleanup/formatting nits in this patch. I've added some minor review comments, but overall the changes in this PR look good to me. test/jdk/java/net/Socket/asyncClose/Leaky.java line 166: > 164: future1.get(); > 165: } finally { > 166: future2.get(); Should we capture/report any exception thrown from `future1.get()`? In its current form that might be lost if even `future2.get()` throws some other exception. test/jdk/java/net/Socket/asyncClose/Leaky.java line 217: > 215: } > 216: > 217: // call getSocket to get the value of the SO_REUSEADDR socket option Typo? Should it be "call getOption ..."? ------------- PR: https://git.openjdk.org/jdk/pull/11863 From alanb at openjdk.org Tue Jan 10 13:59:57 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 10 Jan 2023 13:59:57 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Tue, 10 Jan 2023 13:40:29 GMT, Jaikiran Pai wrote: >> java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. >> >> Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. >> >> There are a couple of random cleanup/formatting nits in this patch. > > test/jdk/java/net/ServerSocket/ImplAccept.java line 251: > >> 249: m.setAccessible(true); >> 250: try { >> 251: m.invoke(si, StandardSocketOptions.SO_REUSEADDR); > > If I understand this correctly, we are calling this method just to have the underlying native call to go through and the actual choice of the option name (in this case the SO_REUSEADDR) isn't of any importance? That's right, legacy SocketImpl doesn't define an API to test if has an open socket. ------------- PR: https://git.openjdk.org/jdk/pull/11863 From jpai at openjdk.org Tue Jan 10 14:03:53 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Tue, 10 Jan 2023 14:03:53 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Thu, 5 Jan 2023 14:39:28 GMT, Alan Bateman wrote: > java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. > > Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. > > There are a couple of random cleanup/formatting nits in this patch. src/java.base/share/classes/java/net/Socket.java line 633: > 631: SocketImpl previous = impl; > 632: impl = si; > 633: state = (SOCKET_CREATED | BOUND | CONNECTED); Could we replace this line with `setConnected()` (which does the same thing as what's being done here)? The reason I say that is because it becomes a bit easier, in a IDE, to see who all calls `setConnected()` and that helps understand which all places in the code trigger this state change. Given the context of this code, I suspect it wouldn't be any noticable impact on performance. This is mostly a nit and you can ignore it if you prefer to keep it in the current form. ------------- PR: https://git.openjdk.org/jdk/pull/11863 From alanb at openjdk.org Tue Jan 10 14:09:56 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 10 Jan 2023 14:09:56 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Tue, 10 Jan 2023 14:01:31 GMT, Jaikiran Pai wrote: >> java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. >> >> Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. >> >> There are a couple of random cleanup/formatting nits in this patch. > > src/java.base/share/classes/java/net/Socket.java line 633: > >> 631: SocketImpl previous = impl; >> 632: impl = si; >> 633: state = (SOCKET_CREATED | BOUND | CONNECTED); > > Could we replace this line with `setConnected()` (which does the same thing as what's being done here)? The reason I say that is because it becomes a bit easier, in a IDE, to see who all calls `setConnected()` and that helps understand which all places in the code trigger this state change. Given the context of this code, I suspect it wouldn't be any noticable impact on performance. > This is mostly a nit and you can ignore it if you prefer to keep it in the current form. In setConnectedImpl it needs to be very clear which state bits are set so I think I'd prefer to leave that as is. ------------- PR: https://git.openjdk.org/jdk/pull/11863 From alanb at openjdk.org Tue Jan 10 14:14:56 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 10 Jan 2023 14:14:56 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Tue, 10 Jan 2023 13:47:17 GMT, Jaikiran Pai wrote: >> java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. >> >> Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. >> >> There are a couple of random cleanup/formatting nits in this patch. > > test/jdk/java/net/Socket/asyncClose/Leaky.java line 166: > >> 164: future1.get(); >> 165: } finally { >> 166: future2.get(); > > Should we capture/report any exception thrown from `future1.get()`? In its current form that might be lost if even `future2.get()` throws some other exception. That's a good idea, in the event that the test fails for some reason. ------------- PR: https://git.openjdk.org/jdk/pull/11863 From jpai at openjdk.org Tue Jan 10 14:42:55 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Tue, 10 Jan 2023 14:42:55 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Tue, 10 Jan 2023 14:06:41 GMT, Alan Bateman wrote: >> src/java.base/share/classes/java/net/Socket.java line 633: >> >>> 631: SocketImpl previous = impl; >>> 632: impl = si; >>> 633: state = (SOCKET_CREATED | BOUND | CONNECTED); >> >> Could we replace this line with `setConnected()` (which does the same thing as what's being done here)? The reason I say that is because it becomes a bit easier, in a IDE, to see who all calls `setConnected()` and that helps understand which all places in the code trigger this state change. Given the context of this code, I suspect it wouldn't be any noticable impact on performance. >> This is mostly a nit and you can ignore it if you prefer to keep it in the current form. > > In setConnectedImpl it needs to be very clear which state bits are set so I think I'd prefer to leave that as is. That's fine with me. ------------- PR: https://git.openjdk.org/jdk/pull/11863 From jpai at openjdk.org Tue Jan 10 14:47:57 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Tue, 10 Jan 2023 14:47:57 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Thu, 5 Jan 2023 14:39:28 GMT, Alan Bateman wrote: > java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. > > Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. > > There are a couple of random cleanup/formatting nits in this patch. With the removal of `synchronized` from the `Socket` APIs, would this require a CSR? ------------- PR: https://git.openjdk.org/jdk/pull/11863 From alanb at openjdk.org Tue Jan 10 14:52:56 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 10 Jan 2023 14:52:56 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Tue, 10 Jan 2023 14:45:28 GMT, Jaikiran Pai wrote: > With the removal of `synchronized` from the `Socket` APIs, would this require a CSR? "synchronized" isn't part of the signature and there isn't any behavior change there. The only change in behavior is in the silly (and unspecified) area of calling implAccept with a connected or closed socket. ------------- PR: https://git.openjdk.org/jdk/pull/11863 From mcimadamore at openjdk.org Tue Jan 10 18:52:56 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Tue, 10 Jan 2023 18:52:56 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Sat, 7 Jan 2023 21:08:07 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: > > Fix incorrect @bug numbers in unit tests. src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java line 2345: > 2343: if (!innerType.hasTag(CLASS) || !outerType.hasTag(CLASS)) > 2344: return false; > 2345: innerType = erasure(innerType); The javac way to write this would be either to compare types using `Types.isSameType` or to compare the underlying class symbols with == (as class symbols are shared across multiple type instances). src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 85: > 83: * > 84: *

> 85: * When tracking references, we distinguish between direct references and indirect references, I'm trying to understand the code and it's not obvious to me as to where this difference comes into play. I believe (but I'm not sure) the spirit is to treat reference to `this` in the original constructor as "direct" while treat a reference to a parameter "a" in a method called from the constructor, where "a" is assigned "this", as indirect? src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1098: > 1096: private void visitLooped(T tree, Consumer visitor) { > 1097: this.visitScoped(tree, false, t -> { > 1098: while (true) { Why is this needed? Can the tracking state of `this` change after multiple "execution" of the same code? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From alanb at openjdk.org Tue Jan 10 19:06:59 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 10 Jan 2023 19:06:59 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: <61qCV0yrvMl0uJlQFfUnoGI8oKH7RjyoQvdOj7FuOv8=.50a6aa91-77fe-4e46-bd3c-166f0ef5eedf@github.com> References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> <61qCV0yrvMl0uJlQFfUnoGI8oKH7RjyoQvdOj7FuOv8=.50a6aa91-77fe-4e46-bd3c-166f0ef5eedf@github.com> Message-ID: On Tue, 10 Jan 2023 13:37:53 GMT, Jaikiran Pai wrote: >> ServerSocket.implAccept is intended to be called with a newly created, and unbound, Socket. We looked at this topic in JDK 13 (see JDK-8225431 and related issues) and decided the behavior is unspecified for silly/broken cases where it is called with a Socket in any other state. It should probably have been specified to throw ISE when introduced in JDK 1.1 but we decided there wasn't enough motive to try to fix the spec for that. This PR touches this area again because it interacts with Socket.close. >> >> So the question is what is the JDK behavior when calling implAccept with a connected Socket. A Socket can't have two connections at the same time. The JDK behavior is to attach the SocketImpl for the newly accepted connection to the Socket. This breaks the association from the Socket to the previous SocketImpl. This PR doesn't change that. It does re-visit the question as to what to do with the now orphaned SocketImpl. Should it be discarded, in which case it may be a resource leak, or should it be closed? The former seems preferable, in which case the read/write methods of streams handed out before calling implAccept will throw IOException. Your question is what happens if the input or output stream close method is called? The spec is that the close method closes the Socket so I've left this as is, it's not changed in this PR. The only real change here is that calling getInputStream/getOutputStream after accepting the new connection will return streams to the newly accepted conn ection. That seems the most sensible thing to do for this crazy case. > > Thank you for that detailed explanation, Alan. That helped. > >> Should it be discarded, in which case it may be a resource leak, or should it be closed? The former seems preferable, in which case the read/write methods of streams handed out before calling implAccept will throw IOException. > > I'm guessing that is a typo and you actually mean "The latter seems preferable ..."? The implementation in this PR does the latter and closes the previous orphaned SocketImpl and I think that's the right thing to do. Sorry, I meant the former as closing seems preferable, ------------- PR: https://git.openjdk.org/jdk/pull/11863 From duke at openjdk.org Tue Jan 10 19:22:58 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 10 Jan 2023 19:22:58 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Mon, 9 Jan 2023 15:03:10 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: >> >> Fix incorrect @bug numbers in unit tests. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 85: > >> 83: * >> 84: *

>> 85: * When tracking references, we distinguish between direct references and indirect references, > > I'm trying to understand the code and it's not obvious to me as to where this difference comes into play. I believe (but I'm not sure) the spirit is to treat reference to `this` in the original constructor as "direct" while treat a reference to a parameter "a" in a method called from the constructor, where "a" is assigned "this", as indirect? It's slightly different from that. Considering any of the various things in scope that can point to an object (these are: the current 'this' instance, the current outer 'this' instance, method parameter/variable, method return value, top of Java stack), such a thing has a "direct" reference if it might possibly _directly_ point to the 'this' we're tracking, while a thing has an "indirect" reference if it might possibly point to the 'this' we're tracking through _at least one level of indirection_. This is just an attempt to eliminate some false positives by distinguishing between those two cases. Originally I was going to try to track fields (in a very limited way), and so this distinction was going to be more important, but even without tracking fields it's still useful. For example, if some method invokes `x.y.foo()` and `x` represents a direct but not an indirect 'this' reference, then there is no leak declared. Considering the other options... (a) if you only track direct references, then you suffer from more false negatives (how many? unclear); (b) if you lump direct and indirect references into one bucket, then you suffer from more false positives (as in previous example `x.y.foo()`). You can see an example of an indirect reference being tracked and exposed in the unit test `ThisEscapeArrayElement.java`. Another motivating example is lambdas. The act of simply _creating_ a lambda never creates a leak, and a lambda never represents a _direct_ reference. But it might represent an _indirect_ reference. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1098: > >> 1096: private void visitLooped(T tree, Consumer visitor) { >> 1097: this.visitScoped(tree, false, t -> { >> 1098: while (true) { > > Why is this needed? Can the tracking state of `this` change after multiple "execution" of the same code? Yes, because the 'this' reference can bounce around through different variables in scope each time around the loop. So we have to repeat the loop until all 'this' references have "flooded" into all the nooks and crannies. The `ThisEscapeLoop.java` unit test demonstrates: public class ThisEscapeLoop { public ThisEscapeLoop() { ThisEscapeLoop ref1 = this; ThisEscapeLoop ref2 = null; ThisEscapeLoop ref3 = null; ThisEscapeLoop ref4 = null; for (int i = 0; i < 100; i++) { ref4 = ref3; ref3 = ref2; ref2 = ref1; if (ref4 != null) ref4.mightLeak(); } } public void mightLeak() { } } ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Tue Jan 10 19:44:56 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 10 Jan 2023 19:44:56 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Mon, 9 Jan 2023 14:23:47 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: >> >> Fix incorrect @bug numbers in unit tests. > > src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java line 2345: > >> 2343: if (!innerType.hasTag(CLASS) || !outerType.hasTag(CLASS)) >> 2344: return false; >> 2345: innerType = erasure(innerType); > > The javac way to write this would be either to compare types using `Types.isSameType` or to compare the underlying class symbols with == (as class symbols are shared across multiple type instances). OK I'm glad you pointed that out because I'm a little unclear on the best way to do this bit. Just to confirm, you are saying that this: `if (erasure(type).equalsIgnoreMetadata(outerType)) {` should be replaced with this? `if (isSameType(type, outerType)) {` ------------- PR: https://git.openjdk.org/jdk/pull/11874 From alanb at openjdk.org Tue Jan 10 20:03:53 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 10 Jan 2023 20:03:53 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup [v2] In-Reply-To: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: > java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. > > Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. > > There are a couple of random cleanup/formatting nits in this patch. Alan Bateman has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains four additional commits since the last revision: - Review comments - Merge - Fix typos - Initial commit ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11863/files - new: https://git.openjdk.org/jdk/pull/11863/files/3d62c906..6184f476 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11863&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11863&range=00-01 Stats: 4754 lines in 215 files changed: 2621 ins; 1179 del; 954 mod Patch: https://git.openjdk.org/jdk/pull/11863.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11863/head:pull/11863 PR: https://git.openjdk.org/jdk/pull/11863 From duke at openjdk.org Tue Jan 10 20:22:16 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Tue, 10 Jan 2023 20:22:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v6] In-Reply-To: References: Message-ID: <-cVR0e9azbb3U9vWObNm1dBbUGIDuI7T6bAOpuPSG8I=.a55f2d47-00ae-471c-a51c-df638c104487@github.com> > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision: Add this-escape to the Javadoc list of strings supported by @SuppressWarnings. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/7e2fdb07..d70d12f4 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=05 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=04-05 Stats: 1 line in 1 file changed: 1 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Tue Jan 10 23:41:19 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Tue, 10 Jan 2023 23:41:19 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: <0Hksmg2eLQg0c9W5CB6y6dXw2vaEXxy-UY9_D0DtLQY=.351da0ec-208c-4f8d-bf16-318de07ca63e@github.com> On Tue, 10 Jan 2023 19:42:06 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java line 2345: >> >>> 2343: if (!innerType.hasTag(CLASS) || !outerType.hasTag(CLASS)) >>> 2344: return false; >>> 2345: innerType = erasure(innerType); >> >> The javac way to write this would be either to compare types using `Types.isSameType` or to compare the underlying class symbols with == (as class symbols are shared across multiple type instances). > > OK I'm glad you pointed that out because I'm a little unclear on the best way to do this bit. > > Just to confirm, you are saying that this: > > `if (erasure(type).equalsIgnoreMetadata(outerType)) {` > > should be replaced with this? > > `if (isSameType(type, outerType)) {` yes ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Tue Jan 10 23:49:12 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Tue, 10 Jan 2023 23:49:12 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: <8PxlV-Syo2Y48TBgSQupSjArfJxMqnA8BZQIYTfYGPA=.057f204c-330b-4fb9-96e5-f8dc8fe348aa@github.com> On Tue, 10 Jan 2023 19:18:04 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 85: >> >>> 83: * >>> 84: *

>>> 85: * When tracking references, we distinguish between direct references and indirect references, >> >> I'm trying to understand the code and it's not obvious to me as to where this difference comes into play. I believe (but I'm not sure) the spirit is to treat reference to `this` in the original constructor as "direct" while treat a reference to a parameter "a" in a method called from the constructor, where "a" is assigned "this", as indirect? > > It's slightly different from that. > > Considering any of the various things in scope that can point to an object (these are: the current 'this' instance, the current outer 'this' instance, method parameter/variable, method return value, top of Java stack), such a thing has a "direct" reference if it might possibly _directly_ point to the 'this' we're tracking, while a thing has an "indirect" reference if it might possibly point to the 'this' we're tracking through _at least one level of indirection_. > > This is just an attempt to eliminate some false positives by distinguishing between those two cases. Originally I was going to try to track fields (in a very limited way), and so this distinction was going to be more important, but even without tracking fields it's still useful. For example, if some method invokes `x.y.foo()` and `x` represents a direct but not an indirect 'this' reference, then there is no leak declared. > > Considering the other options... (a) if you only track direct references, then you suffer from more false negatives (how many? unclear); (b) if you lump direct and indirect references into one bucket, then you suffer from more false positives (as in previous example `x.y.foo()`). > > You can see an example of an indirect reference being tracked and exposed in the unit test `ThisEscapeArrayElement.java`. > > Another motivating example is lambdas. The act of simply _creating_ a lambda never creates a leak, and a lambda never represents a _direct_ reference. But it might represent an _indirect_ reference. So, if I understand correctly your array element test, when we have `new Object[][] { { this } }` the analysis is able to detect that there might be some direct reference nested inside the array. So the outer array is an indirect reference. The inner array is also an indirect reference - but any element accessed on the inner array are direct reference - and so you detect a leak there. Correct? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 00:07:14 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 00:07:14 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: <8PxlV-Syo2Y48TBgSQupSjArfJxMqnA8BZQIYTfYGPA=.057f204c-330b-4fb9-96e5-f8dc8fe348aa@github.com> References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <8PxlV-Syo2Y48TBgSQupSjArfJxMqnA8BZQIYTfYGPA=.057f204c-330b-4fb9-96e5-f8dc8fe348aa@github.com> Message-ID: On Tue, 10 Jan 2023 23:45:59 GMT, Maurizio Cimadamore wrote: >> It's slightly different from that. >> >> Considering any of the various things in scope that can point to an object (these are: the current 'this' instance, the current outer 'this' instance, method parameter/variable, method return value, top of Java stack), such a thing has a "direct" reference if it might possibly _directly_ point to the 'this' we're tracking, while a thing has an "indirect" reference if it might possibly point to the 'this' we're tracking through _at least one level of indirection_. >> >> This is just an attempt to eliminate some false positives by distinguishing between those two cases. Originally I was going to try to track fields (in a very limited way), and so this distinction was going to be more important, but even without tracking fields it's still useful. For example, if some method invokes `x.y.foo()` and `x` represents a direct but not an indirect 'this' reference, then there is no leak declared. >> >> Considering the other options... (a) if you only track direct references, then you suffer from more false negatives (how many? unclear); (b) if you lump direct and indirect references into one bucket, then you suffer from more false positives (as in previous example `x.y.foo()`). >> >> You can see an example of an indirect reference being tracked and exposed in the unit test `ThisEscapeArrayElement.java`. >> >> Another motivating example is lambdas. The act of simply _creating_ a lambda never creates a leak, and a lambda never represents a _direct_ reference. But it might represent an _indirect_ reference. > > So, if I understand correctly your array element test, when we have `new Object[][] { { this } }` the analysis is able to detect that there might be some direct reference nested inside the array. So the outer array is an indirect reference. The inner array is also an indirect reference - but any element accessed on the inner array are direct reference - and so you detect a leak there. Correct? Yes - although it's not tracked being tracked any more precisely than "one or more levels of indirection". And of course by "reference" we only mean "the possibility of a reference" - in general we don't know for sure. Here's the logic: * The analysis knows `this` is a direct reference * Therefore the array expression `{ this }` has an indirect reference (but no direct reference) * The outer array expression `{ { this } }` therefore _also_ has an indirect reference (but no direct reference) At this point, we don't know how many levels of indirection there are in `array` though.... only that its ? 1. * There expression `array[0]` therefore is determined to have both direct and indirect references (they are both _possible_ because we've dereferenced something with an indirect reference) * As does `array[0][0]` for the same reason So invoking `array[0][0].hashCode()` means invoking `hashCode()` on something that has a possible direct reference, and is therefore a leak. Note that because of the imprecision in the number of levels of indirection, invoking `array[0].hashCode()` would also have generated a warning - but in that case, a false positive. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Wed Jan 11 00:07:15 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Wed, 11 Jan 2023 00:07:15 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Tue, 10 Jan 2023 19:20:35 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1098: >> >>> 1096: private void visitLooped(T tree, Consumer visitor) { >>> 1097: this.visitScoped(tree, false, t -> { >>> 1098: while (true) { >> >> Why is this needed? Can the tracking state of `this` change after multiple "execution" of the same code? > > Yes, because the 'this' reference can bounce around through different variables in scope each time around the loop. So we have to repeat the loop until all 'this' references have "flooded" into all the nooks and crannies. > > The `ThisEscapeLoop.java` unit test demonstrates: > > public class ThisEscapeLoop { > > public ThisEscapeLoop() { > ThisEscapeLoop ref1 = this; > ThisEscapeLoop ref2 = null; > ThisEscapeLoop ref3 = null; > ThisEscapeLoop ref4 = null; > for (int i = 0; i < 100; i++) { > ref4 = ref3; > ref3 = ref2; > ref2 = ref1; > if (ref4 != null) > ref4.mightLeak(); > } > } > > public void mightLeak() { > } > } So, if the code was be like this: ThisEscapeLoop ref11 = this; ThisEscapeLoop ref12 = null; ThisEscapeLoop ref13 = null; ThisEscapeLoop ref14 = null; for (int i = 0; i < 100; i++) { ref14 = ref13; ref13 = ref12; ref12 = ref11; ThisEscapeLoop ref21 = ref14; ThisEscapeLoop ref22 = null; ThisEscapeLoop ref23 = null; ThisEscapeLoop ref24 = null; for (int i = 0; i < 100; i++) { ref24 = ref23; ref23 = ref22; ref22 = ref21; if (ref24 != null) ref24.mightLeak(); } } Then it would take not 3 iterations but 3 * 3 to figure out that it is a potential leak? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 00:25:10 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 00:25:10 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Wed, 11 Jan 2023 00:04:14 GMT, Maurizio Cimadamore wrote: >> Yes, because the 'this' reference can bounce around through different variables in scope each time around the loop. So we have to repeat the loop until all 'this' references have "flooded" into all the nooks and crannies. >> >> The `ThisEscapeLoop.java` unit test demonstrates: >> >> public class ThisEscapeLoop { >> >> public ThisEscapeLoop() { >> ThisEscapeLoop ref1 = this; >> ThisEscapeLoop ref2 = null; >> ThisEscapeLoop ref3 = null; >> ThisEscapeLoop ref4 = null; >> for (int i = 0; i < 100; i++) { >> ref4 = ref3; >> ref3 = ref2; >> ref2 = ref1; >> if (ref4 != null) >> ref4.mightLeak(); >> } >> } >> >> public void mightLeak() { >> } >> } > > So, if the code was be like this: > > > ThisEscapeLoop ref11 = this; > ThisEscapeLoop ref12 = null; > ThisEscapeLoop ref13 = null; > ThisEscapeLoop ref14 = null; > for (int i = 0; i < 100; i++) { > ref14 = ref13; > ref13 = ref12; > ref12 = ref11; > ThisEscapeLoop ref21 = ref14; > ThisEscapeLoop ref22 = null; > ThisEscapeLoop ref23 = null; > ThisEscapeLoop ref24 = null; > for (int i = 0; i < 100; i++) { > ref24 = ref23; > ref23 = ref22; > ref22 = ref21; > if (ref24 != null) > ref24.mightLeak(); > } > } > > > Then it would take not 3 iterations but 3 * 3 to figure out that it is a potential leak? Actually I think it would take 1 + 1 + 3 iterations. During the first two iterations of the outer loop, nothing changes after the first go round of the inner loop - i.e., the total set of possible references in existence does not change, because all of the assignments in the inner loop won't involve any 'this' references. It's only the during the third iteration of the outer loop that any 'this' references seep into any of the variables seen by the inner loop. Then it will take 3 cycles for the reference set to converge again. However, this is not to say that there aren't some pathological examples out there. I guess the question is could they exist in "normal" code. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From jpai at openjdk.org Wed Jan 11 00:56:21 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 11 Jan 2023 00:56:21 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup [v2] In-Reply-To: References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Tue, 10 Jan 2023 20:03:53 GMT, Alan Bateman wrote: >> java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. >> >> Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. >> >> There are a couple of random cleanup/formatting nits in this patch. > > Alan Bateman has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains four additional commits since the last revision: > > - Review comments > - Merge > - Fix typos > - Initial commit The changes in this PR look good to me. (Leaky.java line 231 has a typo in a comment, that I think you missed, but that's a trivial thing) ------------- Marked as reviewed by jpai (Reviewer). PR: https://git.openjdk.org/jdk/pull/11863 From duke at openjdk.org Wed Jan 11 03:30:03 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 03:30:03 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: - Use the more appropriate Type comparison method Types.isSameType(). - Add some more comments to clarify how the analysis works. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/d70d12f4..6e96a7d7 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=06 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=05-06 Stats: 31 lines in 2 files changed: 16 ins; 10 del; 5 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 03:30:05 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 03:30:05 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: <0Hksmg2eLQg0c9W5CB6y6dXw2vaEXxy-UY9_D0DtLQY=.351da0ec-208c-4f8d-bf16-318de07ca63e@github.com> References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0Hksmg2eLQg0c9W5CB6y6dXw2vaEXxy-UY9_D0DtLQY=.351da0ec-208c-4f8d-bf16-318de07ca63e@github.com> Message-ID: <7jUSzUYT_eWYGbHkDes10f2-1i5DNdmDGDACe8qsXU4=.5bca0f1b-e004-48bc-87e0-48d6fb9deb96@github.com> On Tue, 10 Jan 2023 23:38:14 GMT, Maurizio Cimadamore wrote: >> OK I'm glad you pointed that out because I'm a little unclear on the best way to do this bit. >> >> Just to confirm, you are saying that this: >> >> `if (erasure(type).equalsIgnoreMetadata(outerType)) {` >> >> should be replaced with this? >> >> `if (isSameType(type, outerType)) {` > > yes Thanks... updated in `6e96a7d76f8`. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From alanb at openjdk.org Wed Jan 11 08:27:13 2023 From: alanb at openjdk.org (Alan Bateman) Date: Wed, 11 Jan 2023 08:27:13 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup [v2] In-Reply-To: References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: <_Atu-YaDxUK9FOM6fbrsN-iGaOM8U3u5pRiF9sbeWw8=.67536fc9-8eb2-49a6-8cdf-06fa30b34e67@github.com> On Wed, 11 Jan 2023 00:53:21 GMT, Jaikiran Pai wrote: > (Leaky.java line 231 has a typo in a comment, that I think you missed, but that's a trivial thing) Well spotted, I fixed the typo in another place so missed it in Leaky. ------------- PR: https://git.openjdk.org/jdk/pull/11863 From alanb at openjdk.org Wed Jan 11 09:57:58 2023 From: alanb at openjdk.org (Alan Bateman) Date: Wed, 11 Jan 2023 09:57:58 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup [v3] In-Reply-To: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: > java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. > > Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. > > There are a couple of random cleanup/formatting nits in this patch. Alan Bateman has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains six additional commits since the last revision: - Fix comment - Merge - Review comments - Merge - Fix typos - Initial commit ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11863/files - new: https://git.openjdk.org/jdk/pull/11863/files/6184f476..71900694 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11863&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11863&range=01-02 Stats: 817 lines in 42 files changed: 408 ins; 319 del; 90 mod Patch: https://git.openjdk.org/jdk/pull/11863.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11863/head:pull/11863 PR: https://git.openjdk.org/jdk/pull/11863 From jpai at openjdk.org Wed Jan 11 10:01:16 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 11 Jan 2023 10:01:16 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup [v3] In-Reply-To: References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Wed, 11 Jan 2023 09:57:58 GMT, Alan Bateman wrote: >> java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. >> >> Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. >> >> There are a couple of random cleanup/formatting nits in this patch. > > Alan Bateman has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains six additional commits since the last revision: > > - Fix comment > - Merge > - Review comments > - Merge > - Fix typos > - Initial commit Marked as reviewed by jpai (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/11863 From mcimadamore at openjdk.org Wed Jan 11 14:15:18 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Wed, 11 Jan 2023 14:15:18 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Wed, 11 Jan 2023 00:22:03 GMT, Archie L. Cobbs wrote: >> So, if the code was be like this: >> >> >> ThisEscapeLoop ref11 = this; >> ThisEscapeLoop ref12 = null; >> ThisEscapeLoop ref13 = null; >> ThisEscapeLoop ref14 = null; >> for (int i = 0; i < 100; i++) { >> ref14 = ref13; >> ref13 = ref12; >> ref12 = ref11; >> ThisEscapeLoop ref21 = ref14; >> ThisEscapeLoop ref22 = null; >> ThisEscapeLoop ref23 = null; >> ThisEscapeLoop ref24 = null; >> for (int i = 0; i < 100; i++) { >> ref24 = ref23; >> ref23 = ref22; >> ref22 = ref21; >> if (ref24 != null) >> ref24.mightLeak(); >> } >> } >> >> >> Then it would take not 3 iterations but 3 * 3 to figure out that it is a potential leak? > > Actually I think it would take 1 + 1 + 3 iterations. > > During the first two iterations of the outer loop, nothing changes after the first go round of the inner loop - i.e., the total set of possible references in existence does not change, because all of the assignments in the inner loop won't involve any 'this' references. > > It's only the during the third iteration of the outer loop that any 'this' references seep into any of the variables seen by the inner loop. Then it will take 3 cycles for the reference set to converge again. > > However, this is not to say that there aren't some pathological examples out there. I guess the question is could they exist in "normal" code. True - probably 3 * 3 can be achieved if this: ThisEscapeLoop ref21 = ref14; Is replaced with ThisEscapeLoop ref21 = this; In which case the inner loop won't converge immediately (as it will have to propagate from ref21 to ref22 to ref23 to ref24). I guess what I'm uncomfortable with is that we have effectively unbounded computation here (especially when we also consider the fact that the analysis "follows" method bodies as well, if they are found in the same compilation unit). I suggest one experiment where you: 1. downgrade the warnings to notes (so that they won't make the JDK build fail) 2. enable this Lint everywhere 3. compare JDK `clean images` time w/ and w/o the Lint ------------- PR: https://git.openjdk.org/jdk/pull/11874 From dfuchs at openjdk.org Wed Jan 11 14:22:15 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Wed, 11 Jan 2023 14:22:15 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup [v3] In-Reply-To: References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: <07OtZQ_lrGeq5JQ_y04ifZcDhl6MpMK3qCs6YDTSIQc=.19a792b1-5f07-44e6-9a15-3cb271881332@github.com> On Wed, 11 Jan 2023 09:57:58 GMT, Alan Bateman wrote: >> java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. >> >> Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. >> >> There are a couple of random cleanup/formatting nits in this patch. > > Alan Bateman has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains six additional commits since the last revision: > > - Fix comment > - Merge > - Review comments > - Merge > - Fix typos > - Initial commit This looks reasonable. It's a bit strange that shutdownInput() / shutdownOutput() are not protected by the same lock than close() but they were not before either. ------------- PR: https://git.openjdk.org/jdk/pull/11863 From mcimadamore at openjdk.org Wed Jan 11 16:02:16 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Wed, 11 Jan 2023 16:02:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: On Wed, 11 Jan 2023 03:30:03 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Use the more appropriate Type comparison method Types.isSameType(). > - Add some more comments to clarify how the analysis works. More questions. Let's say that we only tracked escaping of direct references to `this`. Do you have any sense of how many "less" warnings would be reported in real code (e.g. JDK) ? What I mean by this - let's say that we don't care about tracking _where_ `this` ends up going exactly (e.g. if it's aliased by another variable) - and perhaps also let's say we don't care about inspecting the method to which `this` is leaked too closely - e.g. we treat any early escape of `this` as a possible issue. Of course you could construct examples (like your tests) in which such a simplistic analysis would be defeated. What I'm interested in though is what incremental improvement is brought by the more complex analysis you have in this PR? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Wed Jan 11 16:17:16 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Wed, 11 Jan 2023 16:17:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: On Wed, 11 Jan 2023 14:12:46 GMT, Maurizio Cimadamore wrote: >> Actually I think it would take 1 + 1 + 3 iterations. >> >> During the first two iterations of the outer loop, nothing changes after the first go round of the inner loop - i.e., the total set of possible references in existence does not change, because all of the assignments in the inner loop won't involve any 'this' references. >> >> It's only the during the third iteration of the outer loop that any 'this' references seep into any of the variables seen by the inner loop. Then it will take 3 cycles for the reference set to converge again. >> >> However, this is not to say that there aren't some pathological examples out there. I guess the question is could they exist in "normal" code. > > True - probably 3 * 3 can be achieved if this: > > > ThisEscapeLoop ref21 = ref14; > > Is replaced with > > > ThisEscapeLoop ref21 = this; > > > In which case the inner loop won't converge immediately (as it will have to propagate from ref21 to ref22 to ref23 to ref24). > > I guess what I'm uncomfortable with is that we have effectively unbounded computation here (especially when we also consider the fact that the analysis "follows" method bodies as well, if they are found in the same compilation unit). > > I suggest one experiment where you: > 1. downgrade the warnings to notes (so that they won't make the JDK build fail) > 2. enable this Lint everywhere > 3. compare JDK `clean images` time w/ and w/o the Lint Also, looking at the loop test more closely, it seems to me that what the compiler needs to do is to prove that there can be possible paths by which a `this` can land into ref4. If we build a graph of all the assignments, we get: ref4 <- ref3 <- ref2 <- ref1 <- this So, if we ask "can ref4 possibly contain `this`?" we could "walk" the variable dependencies backwards and discover that, yes, there exist a possible path in which `this` would get there. Now, of course without a loop this can never be a real issue (since you can never send a `this` fully down the chain) - but again, this is a question of how much effort should be spend to handle false negatives in what look like a pathological case. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 18:47:14 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 18:47:14 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> Message-ID: <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> On Wed, 11 Jan 2023 16:14:24 GMT, Maurizio Cimadamore wrote: >> True - probably 3 * 3 can be achieved if this: >> >> >> ThisEscapeLoop ref21 = ref14; >> >> Is replaced with >> >> >> ThisEscapeLoop ref21 = this; >> >> >> In which case the inner loop won't converge immediately (as it will have to propagate from ref21 to ref22 to ref23 to ref24). >> >> I guess what I'm uncomfortable with is that we have effectively unbounded computation here (especially when we also consider the fact that the analysis "follows" method bodies as well, if they are found in the same compilation unit). >> >> I suggest one experiment where you: >> 1. downgrade the warnings to notes (so that they won't make the JDK build fail) >> 2. enable this Lint everywhere >> 3. compare JDK `clean images` time w/ and w/o the Lint > > Also, looking at the loop test more closely, it seems to me that what the compiler needs to do is to prove that there can be possible paths by which a `this` can land into ref4. > > If we build a graph of all the assignments, we get: > > ref4 <- ref3 <- ref2 <- ref1 <- this > > So, if we ask "can ref4 possibly contain `this`?" we could "walk" the variable dependencies backwards and discover that, yes, there exist a possible path in which `this` would get there. > > Now, of course without a loop this can never be a real issue (since you can never send a `this` fully down the chain) - but again, this is a question of how much effort should be spend to handle false negatives in what look like a pathological case. Good idea. Looks like the difference is in the noise, at least on my Macbook: Builds of master (jdk-21+3-69-gc6588d5bb3f) ================================== Build times: real 2m24.650s user 13m46.727s sys 2m33.554s real 2m27.224s user 13m43.464s sys 2m37.251s real 2m26.658s user 13m42.578s sys 2m36.133s Builds of ThisEscape (jdk-21+3-125-g6e96a7d76f8) ================================== Modifications: - Reverted files in the make/ subdirectory to enable warning - Commented out lines 363-382 in ThisEscapeAnalyzer.java so no warnings are actually reported Build times: real 2m25.912s user 13m45.860s sys 2m32.741s real 2m27.213s user 13m44.830s sys 2m36.596s real 2m25.756s user 13m42.889s sys 2m35.659s ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 19:13:16 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 19:13:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> Message-ID: On Wed, 11 Jan 2023 18:44:20 GMT, Archie L. Cobbs wrote: >> Also, looking at the loop test more closely, it seems to me that what the compiler needs to do is to prove that there can be possible paths by which a `this` can land into ref4. >> >> If we build a graph of all the assignments, we get: >> >> ref4 <- ref3 <- ref2 <- ref1 <- this >> >> So, if we ask "can ref4 possibly contain `this`?" we could "walk" the variable dependencies backwards and discover that, yes, there exist a possible path in which `this` would get there. >> >> Now, of course without a loop this can never be a real issue (since you can never send a `this` fully down the chain) - but again, this is a question of how much effort should be spend to handle false negatives in what look like a pathological case. > > Good idea. Looks like the difference is in the noise, at least on my Macbook: > > Builds of master (jdk-21+3-69-gc6588d5bb3f) > ================================== > > Build times: > > real 2m24.650s > user 13m46.727s > sys 2m33.554s > > real 2m27.224s > user 13m43.464s > sys 2m37.251s > > real 2m26.658s > user 13m42.578s > sys 2m36.133s > > Builds of ThisEscape (jdk-21+3-125-g6e96a7d76f8) > ================================== > > Modifications: > > - Reverted files in the make/ subdirectory to enable warning > - Commented out lines 363-382 in ThisEscapeAnalyzer.java > so no warnings are actually reported > > Build times: > > real 2m25.912s > user 13m45.860s > sys 2m32.741s > > real 2m27.213s > user 13m44.830s > sys 2m36.596s > > real 2m25.756s > user 13m42.889s > sys 2m35.659s Regarding the assignment graph approach, I think that would work if the references are bouncing around strictly between variables, but what if the chain includes any of the more complicated stuff that is currently being tracked, such as various Java expressions, method invocations, conditionals, etc.? Consider this example: public class ThisEscapeLoop { public ThisEscapeLoop() { ThisEscapeLoop ref1 = this; ThisEscapeLoop ref2 = null; ThisEscapeLoop ref3 = null; ThisEscapeLoop ref4 = null; for (int i = 0; i < 100; i++) { ref4 = this.returnMe(ref3); ref3 = ref2; ref2 = ref1; if (ref4 != null) ref4.mightLeak(); } } public T returnMe(T x) { return x; } public void mightLeak() { } } If you are only looking at variable assignments with values that are other variables, then the chain "breaks" when `ref4` is assigned indirectly via `returnMe()`, and you miss the leak. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 19:47:16 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 19:47:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: On Wed, 11 Jan 2023 15:59:29 GMT, Maurizio Cimadamore wrote: > What I'm interested in though is what incremental improvement is brought by the more complex analysis you have in this PR? It's a good question. Here are some thoughts... One meta-goal is that this analysis be conservative. In other words, if your code does NOT generate any warnings, then you should feel confident that there is a high probability that there are no leaks. This is analogous to how you can be confident that you won't get any `ClassCastExceptions` at runtime if your code doesn't generate any `unchecked` warnings at compile time. I think this point is generally agreed upon. If so, then we would want?any simpler analysis to err on the side of generating more false positives rather than more false negatives. Assuming that, then the question comes down to a trade-off between code complexity vs. rate of false positives. >From my casual looking over the JDK, the current algorithm generates very few false positives - almost all of the warnings represent actual leaks (I'd be interested in any false positives you do see). (Of course, an irony is that most of these leaks have no real-world effect. For example package-private classes in the JDK (a) have already been debugged long ago, so any intra-package bugs due to 'this' escapes have already been fixed; and (b) are unlikely to be subclassed by anyone. And the ones that have a real-world effect (e.g., `HashSet(Collection)`) can't be fixed because of backward compatibility concerns. So this warning is most useful when writing new code.) So the current code is clearly "complex enough" already. FWIW that's ~975 lines of code excluding blank lines and comments. Now to answer your question about a theoretical simpler analysis: > let's say that we don't care about tracking where `this` ends up going exactly (e.g. if it's aliased by another variable) - and perhaps also let's say we don't care about inspecting the method to which `this` is leaked too closely - e.g. we treat any early escape of this as a possible issue. I'm not sure I completely understand the semantics. But are you saying that if a constructor invokes a private or static method, then this simpler analysis would always declare a leak? If that's the case then I think there are a lot of new false positives, because this is common in constructors. I would then worry that if we dilute the warnings with a bunch of new false positives people are just going to get discouraged and turn the warning off completely. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From darcy at openjdk.org Wed Jan 11 20:51:17 2023 From: darcy at openjdk.org (Joe Darcy) Date: Wed, 11 Jan 2023 20:51:17 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: On Wed, 11 Jan 2023 03:30:03 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Use the more appropriate Type comparison method Types.isSameType(). > - Add some more comments to clarify how the analysis works. Per the discussion in "Effective Java" on calling overridable methods in a constructor, future refinements of the check under review here could be extended to examine the bodies of clone and readObject methods. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Wed Jan 11 21:48:18 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Wed, 11 Jan 2023 21:48:18 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> Message-ID: <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboIFFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> On Wed, 11 Jan 2023 19:10:04 GMT, Archie L. Cobbs wrote: >> Good idea. Looks like the difference is in the noise, at least on my Macbook: >> >> Builds of master (jdk-21+3-69-gc6588d5bb3f) >> ================================== >> >> Build times: >> >> real 2m24.650s >> user 13m46.727s >> sys 2m33.554s >> >> real 2m27.224s >> user 13m43.464s >> sys 2m37.251s >> >> real 2m26.658s >> user 13m42.578s >> sys 2m36.133s >> >> Builds of ThisEscape (jdk-21+3-125-g6e96a7d76f8) >> ================================== >> >> Modifications: >> >> - Reverted files in the make/ subdirectory to enable warning >> - Commented out lines 363-382 in ThisEscapeAnalyzer.java >> so no warnings are actually reported >> >> Build times: >> >> real 2m25.912s >> user 13m45.860s >> sys 2m32.741s >> >> real 2m27.213s >> user 13m44.830s >> sys 2m36.596s >> >> real 2m25.756s >> user 13m42.889s >> sys 2m35.659s > > Regarding the assignment graph approach, I think that would work if the references are bouncing around strictly between variables, but what if the chain includes any of the more complicated stuff that is currently being tracked, such as various Java expressions, method invocations, conditionals, etc.? > > Consider this example: > > public class ThisEscapeLoop { > > public ThisEscapeLoop() { > ThisEscapeLoop ref1 = this; > ThisEscapeLoop ref2 = null; > ThisEscapeLoop ref3 = null; > ThisEscapeLoop ref4 = null; > for (int i = 0; i < 100; i++) { > ref4 = this.returnMe(ref3); > ref3 = ref2; > ref2 = ref1; > if (ref4 != null) > ref4.mightLeak(); > } > } > > public T returnMe(T x) { > return x; > } > > public void mightLeak() { > } > } > > If you are only looking at variable assignments with values that are other variables, then the chain "breaks" when `ref4` is assigned indirectly via `returnMe()`, and you miss the leak. > Good idea. Looks like the difference is in the noise, at least on my Macbook: > > ``` > Builds of master (jdk-21+3-69-gc6588d5bb3f) > ================================== > > Build times: > > real 2m24.650s > user 13m46.727s > sys 2m33.554s > > real 2m27.224s > user 13m43.464s > sys 2m37.251s > > real 2m26.658s > user 13m42.578s > sys 2m36.133s > > Builds of ThisEscape (jdk-21+3-125-g6e96a7d76f8) > ================================== > > Modifications: > > - Reverted files in the make/ subdirectory to enable warning > - Commented out lines 363-382 in ThisEscapeAnalyzer.java > so no warnings are actually reported > > Build times: > > real 2m25.912s > user 13m45.860s > sys 2m32.741s > > real 2m27.213s > user 13m44.830s > sys 2m36.596s > > real 2m25.756s > user 13m42.889s > sys 2m35.659s > ``` Thanks for trying it out - good to know that build time isn't affected. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Wed Jan 11 21:54:17 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Wed, 11 Jan 2023 21:54:17 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboIFFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Wed, 11 Jan 2023 21:45:20 GMT, Maurizio Cimadamore wrote: >> Regarding the assignment graph approach, I think that would work if the references are bouncing around strictly between variables, but what if the chain includes any of the more complicated stuff that is currently being tracked, such as various Java expressions, method invocations, conditionals, etc.? >> >> Consider this example: >> >> public class ThisEscapeLoop { >> >> public ThisEscapeLoop() { >> ThisEscapeLoop ref1 = this; >> ThisEscapeLoop ref2 = null; >> ThisEscapeLoop ref3 = null; >> ThisEscapeLoop ref4 = null; >> for (int i = 0; i < 100; i++) { >> ref4 = this.returnMe(ref3); >> ref3 = ref2; >> ref2 = ref1; >> if (ref4 != null) >> ref4.mightLeak(); >> } >> } >> >> public T returnMe(T x) { >> return x; >> } >> >> public void mightLeak() { >> } >> } >> >> If you are only looking at variable assignments with values that are other variables, then the chain "breaks" when `ref4` is assigned indirectly via `returnMe()`, and you miss the leak. > >> Good idea. Looks like the difference is in the noise, at least on my Macbook: >> >> ``` >> Builds of master (jdk-21+3-69-gc6588d5bb3f) >> ================================== >> >> Build times: >> >> real 2m24.650s >> user 13m46.727s >> sys 2m33.554s >> >> real 2m27.224s >> user 13m43.464s >> sys 2m37.251s >> >> real 2m26.658s >> user 13m42.578s >> sys 2m36.133s >> >> Builds of ThisEscape (jdk-21+3-125-g6e96a7d76f8) >> ================================== >> >> Modifications: >> >> - Reverted files in the make/ subdirectory to enable warning >> - Commented out lines 363-382 in ThisEscapeAnalyzer.java >> so no warnings are actually reported >> >> Build times: >> >> real 2m25.912s >> user 13m45.860s >> sys 2m32.741s >> >> real 2m27.213s >> user 13m44.830s >> sys 2m36.596s >> >> real 2m25.756s >> user 13m42.889s >> sys 2m35.659s >> ``` > > Thanks for trying it out - good to know that build time isn't affected. > Regarding the assignment graph approach, I think that would work if the references are bouncing around strictly between variables, but what if the chain includes any of the more complicated stuff that is currently being tracked, such as various Java expressions, method invocations, conditionals, etc.? > > Consider this example: > > ```java > public class ThisEscapeLoop { > > public ThisEscapeLoop() { > ThisEscapeLoop ref1 = this; > ThisEscapeLoop ref2 = null; > ThisEscapeLoop ref3 = null; > ThisEscapeLoop ref4 = null; > for (int i = 0; i < 100; i++) { > ref4 = this.returnMe(ref3); > ref3 = ref2; > ref2 = ref1; > if (ref4 != null) > ref4.mightLeak(); > } > } > > public T returnMe(T x) { > return x; > } > > public void mightLeak() { > } > } > ``` > > If you are only looking at variable assignments with values that are other variables, then the chain "breaks" when `ref4` is assigned indirectly via `returnMe()`, and you miss the leak. So, in this example though you are calling an instance method before the object is initialized, which would seem to me like a leak (leaving aside heroics to try and chase the method body and see what the body of the method actually does). And, if the method is static, same story - you are passing `ref3` somewhere else, and `ref3` potentially contains `this`. While I know that this is not perfect, and bound to generate false positives, I get the spirit of my question is, really: is there a (much) simpler scheme we can get away with, which has bounded complexity, and which has the property we care about (which seems to be no false negative). I'm less worried about contrived cases emitting false positives, as it's an optional warning that can be shut down - but I'd like perhaps to move the discussion from trying to detect _precisely_ if the leak happens to try to detect if _potentially_ a leak can happen, and see if there's some simpler analysis that can be used to get there (e.g. one which doesn't require flooding). It's possible that you have already considered all these options and the analysis you have here is the best trade off between complexity and precision - but I'd like to have a better understanding of what the trade offs are, and, more importantly, what happens to real code when we tweak the analysis this or that way (as this is a problem where I feel it's easy to get in the land of diminishing returns). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Wed Jan 11 22:43:16 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Wed, 11 Jan 2023 22:43:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Wed, 11 Jan 2023 21:51:45 GMT, Maurizio Cimadamore wrote: > So, in this example though you are calling an instance method before the object is initialized, which would seem to me like a leak D'oh, you're right. But if you made `returnMe()` static or private then the argument would still hold. > And, if the method is static, same story - you are passing ref3 somewhere else, and ref3 potentially contains this. Not true... static methods are safe to "invoke" because they can't be overridden. When the analyzer "invokes" the method, it will see that all it does with its parameter is return it. In other words, any method (or constructor) in the current compilation unit that can't be overridden is never considered "somewhere else". > While I know that this is not perfect, and bound to generate false positives, I get the spirit of my question is, really: is there a (much) simpler scheme we can get away with, which has bounded complexity, and which has the property we care about (which seems to be no false negative). I'm less worried about contrived cases emitting false positives, as it's an optional warning that can be shut down - but I'd like perhaps to move the discussion from trying to detect precisely if the leak happens to try to detect if potentially a leak can happen, and see if there's some simpler analysis that can be used to get there (e.g. one which doesn't require flooding). It's possible that you have already considered all these options and the analysis you have here is the best trade off between complexity and precision - but I'd like to have a better understanding of what the trade offs are, and, more importantly, what happens to real code when we tweak the analysis this or that way (as this is a problem where I feel it's easy to get in the land of diminishing returns). I can only report from my own experience. I thought about this a bit and tried a few different things and what I ended up was the best I could come up with in terms of that trade-off. Of course there was a good bit of intuition and SWAG'ing in that and also a lot of thought experiments. Of course if you have a clever idea for how to do this in a simpler way that achieves basically the same result, I'm all ears :) But I don't really have an analysis of all the trade-offs. Really, at a certain point I stumbled on what I thought was a fairly straightforward way to achieve a good false negative rate and a very low false positive rate, without a lot of work. And frankly at that point I stopped caring about the question you're asking, although I agree it's certainly interesting from an academic point of view (I'm a practical person). A lot of my initial ideas were too simple for my taste, because I could easily find real-world false negatives. An example of "too simple": at first I was not trying to track an outer 'this'. But I found a lot of constructors out there that instantiate nested classes and then do things with them. Without tracking outer 'this' these would all be missed. To take a random example of that: public class FileChooserDemo extends JPanel implements ActionListener { ... public FileChooserDemo() { ... // create a radio listener to listen to option changes OptionListener optionListener = new OptionListener(); // Create options openRadioButton = new JRadioButton("Open"); openRadioButton.setSelected(true); openRadioButton.addActionListener(optionListener); // <- LEAK HERE ... } private class OptionListener implements ActionListener { ... } } That particular leak is (probably) innocuous, but it still qualifies as a leak and should be reported. Note that failing to track an outer 'this' causes false negatives, which are a bigger problem than false positives. On the flip side, I started out trying to explicitly track field references, but that seemed like more complexity than needed, at least for phase 1, so that was left out. The "flooding" aspect didn't really worry me because the reference set is "append only" and there is small, finite set of possible references at each scope, so it can't really get that out of hand. Testing indeed shows it's not a problem. By the way recursion also "floods" until convergence, just like looping. I would have been pleased to find "a much simpler scheme". But the more I thought about those options, the more I came up with easy misses. And after a certain point, it actually became easier to simply "execute" the code by scanning the AST while carrying around a `Set` to track possible references. It's really that simple. Instead of trying to be "smart" we just let the code tell us what happens. Apologies if this is not a very good answer to your question. In the big picture, the false positive rate is traded-off against code complexity, and we want the best possible trade-off, right? But how are you defining "complexity"? If you really mean performance, then I don't see a problem... the JDK build times are essentially unchanged. If you mean lines of code or whatever, then it doesn't seem inordinate. And the algorithm is more or less just an AST scan, like lots of other examples in the compiler code. So I don't see a problem there either. Yes, there may be a much simpler way that's just as good, but if I could have thought of it I would have already. Perhaps you or someone else has better insight. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 00:18:11 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 00:18:11 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Wed, 11 Jan 2023 22:40:43 GMT, Archie L. Cobbs wrote: > > D'oh, you're right. But if you made `returnMe()` static or private then the argument would still hold. > > > And, if the method is static, same story - you are passing ref3 somewhere else, and ref3 potentially contains this. > > Not true... static methods are safe to "invoke" because they can't be overridden. When the analyzer "invokes" the method, it will see that all it does with its parameter is return it. > So, for static methods, it could go down two ways: either we don't even look at referenced method bodies, give up and just declare "sorry, escaping". Or, if we look into method bodies, and see that the relationship between inner and outer parameter is as simple, it's just like assignment again: ref1 -> ref2 -> ref3 -> x -> ref4 > But I don't really have an analysis of all the trade-offs. Really, at a certain point I stumbled on what I thought was a fairly straightforward way to achieve a good false negative rate and a very low false positive rate, without a lot of work. And frankly at that point I stopped caring about the question you're asking, although I agree it's certainly interesting from an academic point of view (I'm a practical person). The reason I'm asking these questions is that I'm trying to understand which ingredients went into the analysis and why, in order to try and build a mental problem of what the problem that needs to be solved is, what are the constraints, etc. I'm also a practical person :-) and I often find it easier to understand a piece of code if I know some of the reasoning that went behind it, or what's the behavior supposed to be. I do not know, off-hands, whether there is a simpler solution - I was mostly probing for war stories of the kind "I tried X and I got Y", and I apologize if that came off the wrong way. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 02:17:16 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 02:17:16 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Thu, 12 Jan 2023 00:15:08 GMT, Maurizio Cimadamore wrote: > So, for static methods, it could go down two ways: either we don't even look at referenced method bodies, give up and just declare "sorry, escaping". Or, if we look into method bodies, and see that the relationship between inner and outer parameter is as simple, it's just like assignment again: Right - and just to reconfirm, it's only the non-overridable methods in the same compilation unit that are "invoked" (i.e., analyzed & tracked). Any method that (might) exist in another compilation unit is off limits, so we have to assume the worst case and declare a leak if we are passing it any 'this' references. > in order to try and build a mental problem of what the problem that needs to be solved is Gotcha. Let's be clear about what exactly we're worrying about. It's this situation: You have a class `B extends A`, where `B` and `A` are in different compilation units, and during the `super()` call that constructor `B()` makes to its superclass constructor `A()`, some code in class `B` gets executed (really, it's some field in `B` getting accessed that actually matters) prior to `A()` returning. So the basic goal is to analyze `A` constructors and watch 'this' references until if/when they go to someplace where we can no longer watch them. At that point we have to assume that some code in `B` might get invoked and so we generate a warning. OK, so where can a 'this' reference go? Well, here are all of the possible places a Java reference can exist: 1. On the Java stack (a) The current 'this' instance (b) A method parameter (c) A local variable (d) A temporary value that is part of the current expression being evaluated (e) The return value from a method that just returned (f) A caught exception 1. In a field of some object... (a) A normal field (b) An outer 'this' instance (c) Other synthetic field (e.g., captured free variable) 1. As an element in a reference array 1. In native code as a native reference Those are the only possibilities AFAIK. So one way to locate yourself on the spectrum from "simple" to "complex" is to answer this question: Which of those are you going to try to keep track of, and for each one, how hard are you going to try? The `this-escape` analysis being proposed tracks 1(a-e) and 2(b) pretty closely (it tries hard), and it adds a very course tracking of 2(a-c), and 3 using the notion of indirect references (it doesn't try very hard). We do not track 1(f) or 4. So to think about the overall problem, imagine how you might or might not address all of those cases. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From alanb at openjdk.org Thu Jan 12 08:02:15 2023 From: alanb at openjdk.org (Alan Bateman) Date: Thu, 12 Jan 2023 08:02:15 GMT Subject: RFR: 8278326: Socket close is not thread safe and other cleanup [v3] In-Reply-To: <07OtZQ_lrGeq5JQ_y04ifZcDhl6MpMK3qCs6YDTSIQc=.19a792b1-5f07-44e6-9a15-3cb271881332@github.com> References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> <07OtZQ_lrGeq5JQ_y04ifZcDhl6MpMK3qCs6YDTSIQc=.19a792b1-5f07-44e6-9a15-3cb271881332@github.com> Message-ID: On Wed, 11 Jan 2023 14:19:01 GMT, Daniel Fuchs wrote: > It's a bit strange that shutdownInput() / shutdownOutput() are not protected by the same lock than close() but they were not before either. Thanks for going through this. The shutdownXXX methods require the Socket to be connected so they don't create the SocketImpl or the underlying socket. It's okay for these methods to race with each other, or close, as it will be handled by the SocketImpl (NioSocketImpl). ------------- PR: https://git.openjdk.org/jdk/pull/11863 From alanb at openjdk.org Thu Jan 12 09:42:28 2023 From: alanb at openjdk.org (Alan Bateman) Date: Thu, 12 Jan 2023 09:42:28 GMT Subject: Integrated: 8278326: Socket close is not thread safe and other cleanup In-Reply-To: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> References: <_r__FFM-HFJwp31gepdY2vZDHigM0P3o9AFFmrTw-D0=.51d73c75-08b8-4d85-97e1-f77da1e6f806@github.com> Message-ID: On Thu, 5 Jan 2023 14:39:28 GMT, Alan Bateman wrote: > java.net.Socket is not specified to be thread safe but it is required to support async close. If you create an unbound Socket and close it at around the time that another thread is binding, connecting, or anything else that creates the underlying socket then it can leak. The simplest thing to do is to synchronize all methods but the underlying SocketImpl implementation is thread safe, and all we really need is for Socket (and ServerSocket) to synchronize the creation of the underlying socket (SocketImpl.create) with close. As part of this change I've replaced the 6 flags with a bit mask. A new test is added to the Socket/asyncClose directory to test closing concurrently with another operation, the test will detect if the closed Socket is connected to a SocketImpl with an open socket. > > Related is that ServerSocket.implAccept can be overridden to provide the Socket to accept. Its behavior is unspecified when called with a Socket that isn't newly created/unbound and there are number of silly scenarios that can arise. I've changed implAccept to coordinate with close so that accept doesn't return a closed Socket that is connected to an underlying socket. A new test is added to exercise these scenarios. > > There are a couple of random cleanup/formatting nits in this patch. This pull request has now been integrated. Changeset: 4b573343 Author: Alan Bateman URL: https://git.openjdk.org/jdk/commit/4b573343a6eb05b8b469177935d48c48957aff64 Stats: 923 lines in 5 files changed: 692 ins; 89 del; 142 mod 8278326: Socket close is not thread safe and other cleanup Reviewed-by: jpai ------------- PR: https://git.openjdk.org/jdk/pull/11863 From mcimadamore at openjdk.org Thu Jan 12 10:00:21 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 10:00:21 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Thu, 12 Jan 2023 02:14:10 GMT, Archie L. Cobbs wrote: >>> >>> D'oh, you're right. But if you made `returnMe()` static or private then the argument would still hold. >>> >>> > And, if the method is static, same story - you are passing ref3 somewhere else, and ref3 potentially contains this. >>> >>> Not true... static methods are safe to "invoke" because they can't be overridden. When the analyzer "invokes" the method, it will see that all it does with its parameter is return it. >>> >> >> So, for static methods, it could go down two ways: either we don't even look at referenced method bodies, give up and just declare "sorry, escaping". Or, if we look into method bodies, and see that the relationship between inner and outer parameter is as simple, it's just like assignment again: >> >> ref1 -> ref2 -> ref3 -> x -> ref4 >> >>> But I don't really have an analysis of all the trade-offs. Really, at a certain point I stumbled on what I thought was a fairly straightforward way to achieve a good false negative rate and a very low false positive rate, without a lot of work. And frankly at that point I stopped caring about the question you're asking, although I agree it's certainly interesting from an academic point of view (I'm a practical person). >> >> The reason I'm asking these questions is that I'm trying to understand which ingredients went into the analysis and why, in order to try and build a mental problem of what the problem that needs to be solved is, what are the constraints, etc. I'm also a practical person :-) and I often find it easier to understand a piece of code if I know some of the reasoning that went behind it, or what's the behavior supposed to be. >> >> I do not know, off-hands, whether there is a simpler solution - I was mostly probing for war stories of the kind "I tried X and I got Y", and I apologize if that came off the wrong way. > >> So, for static methods, it could go down two ways: either we don't even look at referenced method bodies, give up and just declare "sorry, escaping". Or, if we look into method bodies, and see that the relationship between inner and outer parameter is as simple, it's just like assignment again: > > Right - and just to reconfirm, it's only the non-overridable methods in the same compilation unit that are "invoked" (i.e., analyzed & tracked). Any method that (might) exist in another compilation unit is off limits, so we have to assume the worst case and declare a leak if we are passing it any 'this' references. > >> in order to try and build a mental problem of what the problem that needs to be solved is > > Gotcha. > > Let's be clear about what exactly we're worrying about. It's this situation: You have a class `B extends A`, where `B` and `A` are in different compilation units, and during the `super()` call that constructor `B()` makes to its superclass constructor `A()`, some code in class `B` gets executed (really, it's some field in `B` getting accessed that actually matters) prior to `A()` returning. > > So the basic goal is to analyze `A` constructors and watch 'this' references until if/when they go to someplace where we can no longer watch them. At that point we have to assume that some code in `B` might get invoked and so we generate a warning. > > OK, so where can a 'this' reference go? > > Well, here are all of the possible places a Java reference can exist: > 1. On the Java stack > (a) The current 'this' instance > (b) A method parameter > (c) A local variable > (d) A temporary value that is part of the current expression being evaluated > (e) The return value from a method that just returned > (f) A caught exception > 1. In a field of some object... > (a) A normal field > (b) An outer 'this' instance > (c) Other synthetic field (e.g., captured free variable) > 1. As an element in a reference array > 1. In native code as a native reference > > Those are the only possibilities AFAIK. > > So one way to locate yourself on the spectrum from "simple" to "complex" is to answer this question: Which of those are you going to try to keep track of, and for each one, how hard are you going to try? > > The `this-escape` analysis being proposed tracks 1(a-e) and 2(b) pretty closely (it tries hard), and it adds a very course tracking of 2(a-c), and 3 using the notion of indirect references (it doesn't try very hard). We do not track 1(f) or 4. > > So to think about the overall problem, imagine how you might or might not address all of those cases. > * On the Java stack > (a) The current 'this' instance > (b) A method parameter > (c) A local variable > (d) A temporary value that is part of the current expression being evaluated > (e) The return value from a method that just returned > (f) A caught exception > > * In a field of some object... > (a) A normal field > (b) An outer 'this' instance > (c) Other synthetic field (e.g., captured free variable) > > * As an element in a reference array > > * In native code as a native reference Thanks for the classification. This is helpful. I'm not sure what you mean by (1f). You mean `this` can be embedded in an exception being thrown? Is that different from (2)? Also, it seems to me that (3) is a special case of (2) - in the sense that you can imagine a reference array as a big object that has many fields as there are elements - so the same reasoning applies. When looking at (2d) and (2e) the fact that Javac's AST is not in SSA form means that, yes, we need to track _expressions_ not just variables (e.g. for chains of methods calls, ternary operators and such). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From ihse at openjdk.org Thu Jan 12 12:16:18 2023 From: ihse at openjdk.org (Magnus Ihse Bursie) Date: Thu, 12 Jan 2023 12:16:18 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: On Wed, 11 Jan 2023 03:30:03 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Use the more appropriate Type comparison method Types.isSameType(). > - Add some more comments to clarify how the analysis works. FWIW, the make changes look good. I have nothing to say about the actual lint code itself. ------------- Marked as reviewed by ihse (Reviewer). PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 12:31:39 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 12:31:39 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> On Wed, 11 Jan 2023 03:30:03 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Use the more appropriate Type comparison method Types.isSameType(). > - Add some more comments to clarify how the analysis works. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 163: > 161: * invoked from the target constructor; if empty, we're still in the constructor. > 162: */ > 163: private final ArrayDeque callStack = new ArrayDeque<>(); There is a concept of push/popScope and then there's a separate concept of call stack (which is just a list of diagnostic position up to the point). I wonder if this could be better modeled by using a single class e.g. Scope/Frame which has a diagnostic position, plus other useful things. Perhaps it might even be helpful to have a ref set on each scope, so that you don't have to attach a "depth" to each ref - the depth of the ref would be determined by the "scope" in which it appears. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 175: > 173: private DiagnosticPosition[] pendingWarning; > 174: > 175: // These fields are scoped to the CONSTRUCTOR OR INVOKED METHOD BEING ANALYZED Watch out for "all caps" src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 218: > 216: new TreeScanner() { > 217: > 218: private Lint lint = ThisEscapeAnalyzer.this.lint; On a first look I'm not sure about the granularity of suppression here. I believe that suppressing at the class level, or at the constructor level is enough. Allowing to further annotate var declarations and non-constructor methods, while doable, might actually be counter productive - in the sense that the annotation does not occur in the constructor (where you'd want to see it) but in some other method. I think the fact that a constructor is escaping (willingly) should be a visible thing. Something to consider. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 220: > 218: private Lint lint = ThisEscapeAnalyzer.this.lint; > 219: private JCClassDecl currentClass; > 220: private boolean privateOuter; I don't think this is needed - see below src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 227: > 225: final boolean privateOuterPrev = this.privateOuter; > 226: final Lint lintPrev = this.lint; > 227: this.lint = this.lint.augment(tree.sym); general stylistic comment - I see here and everywhere in this class `this.xyz` - this is not the norm in the rest of the javac codebase, and it would be better to replace it with just `xyz` src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 230: > 228: try { > 229: this.currentClass = tree; > 230: this.privateOuter |= tree.sym.isAnonymous(); These can be inlined in the check below src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 270: > 268: final boolean analyzable = this.currentClassIsExternallyExtendable() && > 269: TreeInfo.isConstructor(tree) && > 270: !tree.sym.isPrivate() && Why aren't private constructors analyzed? If we have a class with a private constructor and public static factory invoking said constructor, and the constructor makes `this` escape, isn't that an issue we should detect? src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 294: > 292: !(this.currentClass.sym.isSealed() && this.currentClass.permitting.isEmpty()) && > 293: !(this.currentClass.sym.owner.kind == MTH) && > 294: !this.privateOuter; Here, note that is the owner of the current class symbol is a method, that covers anonymous classes too, which is a part of `privateOuter`. So the only think we need to check here is whether "currentClass" is private, which is a simple predicate. No need to carry `privateOuter` I believe src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 304: > 302: > 303: // We are looking for analyzable constructors only > 304: final Symbol sym = entry.getKey(); This seems unused. And, if so, perhaps we only need a `Set`, not a map. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 348: > 346: final Comparator ordering = (warning1, warning2) -> { > 347: for (int index1 = 0, index2 = 0; true; index1++, index2++) { > 348: final boolean end1 = index1 >= warning1.length; Another stylistic comment - the `final` here is not super helpful. The compiler performs effectively final analysis, so if your locals are only written once, you are good to go - and can even use them inside lambdas. From a documentation perspective it might carry a bit of value, but again, the rest of the javac code generally doesn't do that. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 411: > 409: final boolean referenceExpressionNode; > 410: switch (tree.getTag()) { > 411: case CASE: surprised to see `CASE` here - as that's not an expression src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 444: > 442: if (referenceExpressionNode) { > 443: > 444: // We treat instance methods as having a "value" equal to their instance The comment is slightly misleading - e.g. I'd suggest clarifying "having a "value" whose type is the same as that of the class in which the method is defined" src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 454: > 452: > 453: // If the expression type is incompatible with 'this', discard it > 454: if (type != null && !this.isSubtype(this.targetClass.sym.type, type)) Instead of adding the direct reference, and then having to check if the reference needs to be removed, would it be possible not to add the reference in the first place if the types mismatch? src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 504: > 502: // Recurse on method expression > 503: this.scan(invoke.meth); > 504: final boolean direct = this.refs.remove(ExprRef.direct(this.depth)); Understanding checkpoint. Considering this code: rec.m() There are two cases: * `rec` might be a direct reference to this (e.g. a local) * `rec` might be an indirect reference to this (a lambda containing `this`) So the receiver of the method might be direct or indirect. This will then determine how to interpret `this` in the context of that method analysis - e.g. when we see a `JCIdent` for `this`, we create a direct/indirect `ExprRef` based on what the receiver kind was. Correct? src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 817: > 815: // Methods - the "value" of a non-static method is a reference to its instance > 816: final Symbol sym = tree.sym; > 817: if (sym.kind == MTH) { This is perhaps where filtering based on the declaring class could make sense (to avoid having to filter later) ? Perhaps this could also be centralized - e.g. whenever you create an ExprRef you also pass the type for it, and if the type matches that for the current class you create it and add to the list, otherwise you skip it. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 875: > 873: // Reference to this? > 874: if (tree.name == names._this || tree.name == names._super) { > 875: if (this.refs.contains(ThisRef.direct())) This idiom occurs quite a lot. If I'm correct, this basically amounts at asking as to whether the receiver of the method we're currently evaluating is direct or not (which is an invariant, given a method body - e.g. for a given method this "fact" should stay the same). If that's the case, perhaps capturing this in a flag could be better - then you could have just have a single method e.g. `XYZRef.create(boolean direct)`, and remove the branching (here and elsewhere). src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 900: > 898: final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; > 899: final Type methodOwnerType = sym.owner.type; > 900: if (this.isSubtype(currentClassType, methodOwnerType)) { I believe what you need here is not subtyping but subclassing - see `Symbol.isSubclass` src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 909: > 907: > 908: // Check for implicit outer 'this' reference > 909: if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { Similarly here - look for `Symbol.isEnclosedBy` src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1302: > 1300: * In other words, a reference that's sitting on top of the stack. > 1301: */ > 1302: private static class ExprRef extends Ref { Maybe I'm wrong - but it seems that the only thing we need to track is whether the top of stack (e.g. last evaluated expression) has a direct reference or indirect reference (or none). Do we really need a set for this? (this seems the same as for ThisRef which is used inside method, which can be one of the same three options). While I do see value for tracking which variables are aliases for this (either direct or indirect), it seems like (at least on a superficial look) that expression refs might be replaced by a visitor field/parameter. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1319: > 1317: /** A reference from the return value of the current method being "invoked". > 1318: */ > 1319: private static class ReturnRef extends Ref { Isn't this just an ExprRef? This might also be related with the fact that we deal with return values in different ways than with e.g. values returned from a nested scope (where we just pop, and then copy all pending expression to the outer depth). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 13:04:18 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 13:04:18 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: On Wed, 11 Jan 2023 03:30:03 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Use the more appropriate Type comparison method Types.isSameType(). > - Add some more comments to clarify how the analysis works. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 334: > 332: // of the stack trace of B. For example, if constructor Foo(int x) has a leak, and constructor > 333: // Foo() invokes this(0), then emitting a warning for Foo() would be redundant. > 334: final BiPredicate extendsAsPrefix = (warning1, warning2) -> { Another strategy would be to give a single warning per leaking constructor. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 15:02:22 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 15:02:22 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Thu, 12 Jan 2023 09:57:00 GMT, Maurizio Cimadamore wrote: > I'm not sure what you mean by (1f). You mean this can be embedded in an exception being thrown? Is that different from (2)? Yes, this would be a different case from any other that you'd have to handle in the code if you wanted to deal with it. An example of how this could happen would be: public class ThrownThis extends RuntimeException { public ThrownThis(Object obj) { try { this.validate(obj); } catch (RuntimeException e) { e.mightLeak(); // LEAK HERE } } private void validate(Object obj) { if (obj.hashCode() != 123) throw this; } public void mightLeak() { } } Of course, that's an absurd example and the likelihood that any random piece of actually code does that is negligible. Regardless, I did briefly consider including handling for thrown exceptions but quickly decided it couldn't possibly be worth the trouble. As a result, if you compile that example with `-Xlint:this-escape` you don't get a warning. No major loss! > Also, it seems to me that (3) is a special case of (2) - in the sense that you can imagine a reference array as a big object that has many fields as there are elements - so the same reasoning applies. Yes it's effectively the same thing, but fields and array elements are accessed by different mechanisms in Java, so from the point of the analyzer they have to be handled separately for that reason, which is why I broke them out. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 15:12:56 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 15:12:56 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Thu, 12 Jan 2023 14:59:12 GMT, Archie L. Cobbs wrote: >>> * On the Java stack >>> (a) The current 'this' instance >>> (b) A method parameter >>> (c) A local variable >>> (d) A temporary value that is part of the current expression being evaluated >>> (e) The return value from a method that just returned >>> (f) A caught exception >>> >>> * In a field of some object... >>> (a) A normal field >>> (b) An outer 'this' instance >>> (c) Other synthetic field (e.g., captured free variable) >>> >>> * As an element in a reference array >>> >>> * In native code as a native reference >> >> Thanks for the classification. This is helpful. >> >> I'm not sure what you mean by (1f). You mean `this` can be embedded in an exception being thrown? Is that different from (2)? >> >> Also, it seems to me that (3) is a special case of (2) - in the sense that you can imagine a reference array as a big object that has many fields as there are elements - so the same reasoning applies. >> >> When looking at (2d) and (2e) the fact that Javac's AST is not in SSA form means that, yes, we need to track _expressions_ not just variables (e.g. for chains of methods calls, ternary operators and such). > >> I'm not sure what you mean by (1f). You mean this can be embedded in an exception being thrown? Is that different from (2)? > > Yes, this would be a different case from any other that you'd have to handle in the code if you wanted to deal with it. > > An example of how this could happen would be: > > public class ThrownThis extends RuntimeException { > > public ThrownThis(Object obj) { > try { > this.validate(obj); > } catch (RuntimeException e) { > e.mightLeak(); // LEAK HERE > } > } > > private void validate(Object obj) { > if (obj.hashCode() != 123) > throw this; > } > > public void mightLeak() { > } > } > > Of course, that's an absurd example and the likelihood that any random piece of actually code does that is negligible. > > Regardless, I did briefly consider including handling for thrown exceptions but quickly decided it couldn't possibly be worth the trouble. > > As a result, if you compile that example with `-Xlint:this-escape` you don't get a warning. No major loss! > >> Also, it seems to me that (3) is a special case of (2) - in the sense that you can imagine a reference array as a big object that has many fields as there are elements - so the same reasoning applies. > > Yes it's effectively the same thing, but fields and array elements are accessed by different mechanisms in Java, so from the point of the analyzer they have to be handled separately for that reason, which is why I broke them out. > Yes, this would be a different case from any other that you'd have to handle in the code if you wanted to deal with it. > > An example of how this could happen would be: > > ```java > public class ThrownThis extends RuntimeException { > > public ThrownThis(Object obj) { > try { > this.validate(obj); > } catch (RuntimeException e) { > e.mightLeak(); // LEAK HERE > } > } > > private void validate(Object obj) { > if (obj.hashCode() != 123) > throw this; > } > > public void mightLeak() { > } > } > ``` > Interesting example - I thought you might have been referring to a case where the class being analyzed was itself an exception. Question - shouldn't we conclude that `this` leak when we see `throw this` ? E.g. what if the constructor did not have a `catch` (or if the catch was of a different type) ? > Of course, that's an absurd example and the likelihood that any random piece of actually code does that is negligible. > > Regardless, I did briefly consider including handling for thrown exceptions but quickly decided it couldn't possibly be worth the trouble. > > As a result, if you compile that example with `-Xlint:this-escape` you don't get a warning. No major loss! > > > Also, it seems to me that (3) is a special case of (2) - in the sense that you can imagine a reference array as a big object that has many fields as there are elements - so the same reasoning applies. > > Yes it's effectively the same thing, but fields and array elements are accessed by different mechanisms in Java, so from the point of the analyzer they have to be handled separately for that reason, which is why I broke them out. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 15:19:44 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 15:19:44 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: On Thu, 12 Jan 2023 13:01:44 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 334: > >> 332: // of the stack trace of B. For example, if constructor Foo(int x) has a leak, and constructor >> 333: // Foo() invokes this(0), then emitting a warning for Foo() would be redundant. >> 334: final BiPredicate extendsAsPrefix = (warning1, warning2) -> { > > Another strategy would be to give a single warning per leaking constructor. We already impose a limit of at most one warning per constructor. But for this limit what is technically meant by "per constructor" is "At most one warning per constructor, assuming that constructor is the one being analyzed (i.e., the one invoked by the subclass and not via `this()`)." So that limitation doesn't stop a constructor from generating the same warning multiple times due to it being invoked indirectly by other constructors via `this()`. Those duplicate warnings are what the code above eliminates. So this code only generates one warning, and it's reported for the second constructor: public class DupWarn1 { public DupWarn1() { this(0); } public DupWarn1(int x) { this.mightLeak(); } public void mightLeak() { } } DupWarn1.java:8: warning: [this-escape] possible 'this' escape before subclass is fully initialized this.mightLeak(); ^ This is appropriate. The leak is really in the second constructor; the first constructor has nothing to do with it. Reporting a leak for both constructors would be redundant. An interesting side question: Is it possible to come up with an example where constructor A has a 'this' leak, and some other constructor B invokes `this()` to delegate to A, but when B delegates to A the leak occurs differently, or not at all? Because of the "flood" analysis, and the fact that you can't pass 'this' references to `this()` or `super()` (these are static contexts), I don't think it's possible. So in fact the deduplication will always apply whenever `this()` is involved. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 15:29:30 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 15:29:30 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v5] In-Reply-To: References: <_GkLRl5VTNh8ToJ3cjF-_v9j6eWWQzbUCCKStOXKh4g=.5e9505f1-8182-47e6-a8ed-78982db36c94@github.com> <0VZaG4s1DCehTwPfEshM6Lt90CKit-D-w_4F8NzAw8c=.b515334e-a4d3-495d-afae-6e4aa45ff683@github.com> <8RxCBaG_JM-5ej97lG5SDVzelH018OXgboI FFvs0hmQ=.ec5da5d8-01db-4797-938b-0419a3c1d2ec@github.com> Message-ID: On Thu, 12 Jan 2023 15:10:19 GMT, Maurizio Cimadamore wrote: > Interesting example - I thought you might have been referring to a case where the class being analyzed was itself an exception. Yes - although that example doesn't compile (oops!). Just replace `catch (RuntimeException e)` with `catch (ThrownThis e)` and it should. > Question - shouldn't we conclude that this leak when we see throw this ? E.g. what if the constructor did not have a catch (or if the catch was of a different type) ? A thorough analysis would evaluate whether the exception was caught or not. But you're right - since we're not doing a thorough analysis, we should immediately declare a leak anytime we see `throw x` where `x` is a possible direct or indirect reference. Of course, this scenario should be unlikely in normal code. I will add a check for that. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 16:06:28 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 16:06:28 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 10:18:27 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 294: > >> 292: !(this.currentClass.sym.isSealed() && this.currentClass.permitting.isEmpty()) && >> 293: !(this.currentClass.sym.owner.kind == MTH) && >> 294: !this.privateOuter; > > Here, note that is the owner of the current class symbol is a method, that covers anonymous classes too, which is a part of `privateOuter`. So the only think we need to check here is whether "currentClass" is private, which is a simple predicate. No need to carry `privateOuter` I believe Unless you explicitly declare a nested class `private`, it won't have the `ACC_PRIVATE` flag, even though it is "implicitly private" because it has a `private` enclosing class. Example: $ cat PrivateOuter.java public class PrivateOuter { private static class Inner1 { static class Inner2 { } } } $ javap -v PrivateOuter$Inner1$Inner2 Classfile /Users/archie/proj/jdk/flex-test/classes/PrivateOuter$Inner1$Inner2.class Last modified Jan 12, 2023; size 408 bytes SHA-256 checksum 51ba6d39a5e66df2a078761d6424acbea7a8e32b8451f6ca7d2af49889673b2c Compiled from "PrivateOuter.java" class PrivateOuter$Inner1$Inner2 minor version: 0 major version: 63 flags: (0x0020) ACC_SUPER this_class: #7 // PrivateOuter$Inner1$Inner2 super_class: #2 // java/lang/Object ... So we have to keep track of this "implicit privateness" manually, which is what the `privateOuter` flag is for. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 16:24:37 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 16:24:37 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> On Thu, 12 Jan 2023 10:25:27 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 218: > >> 216: new TreeScanner() { >> 217: >> 218: private Lint lint = ThisEscapeAnalyzer.this.lint; > > On a first look I'm not sure about the granularity of suppression here. I believe that suppressing at the class level, or at the constructor level is enough. Allowing to further annotate var declarations and non-constructor methods, while doable, might actually be counter productive - in the sense that the annotation does not occur in the constructor (where you'd want to see it) but in some other method. I think the fact that a constructor is escaping (willingly) should be a visible thing. Something to consider. Two things... We need to support annotations on field declarations because their initializers are effectively mini-constructors. But we don't need it on local variables, parameters, etc. - too confusing. For annotations on methods, yes it's debatable. It can be handy if you have e.g. an `init()` method that all of your constructors invoke. However, I agree it's also confusing, so I will remove. But we should keep the notion that if a constructor invokes `this()`, and the invoked constructor has annotations suppressed, then we skip over the constructor invocation. I will make these updates. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 304: > >> 302: >> 303: // We are looking for analyzable constructors only >> 304: final Symbol sym = entry.getKey(); > > This seems unused. And, if so, perhaps we only need a `Set`, not a map. Thanks, you're right, the map keys are not used here. I'll clean up the loop. But we still need a map, not a set, because the map is used elsewhere. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 16:31:21 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 16:31:21 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 10:32:19 GMT, Maurizio Cimadamore wrote: > If we have a class with a private constructor and public static factory invoking said constructor, and the constructor makes this escape, isn't that an issue we should detect? A static factory method will not create a subclassed instance, so there's no 'this' escape problem. But I admit I completely missed factory methods as a potential thing to worry about. Is it possible for a leak to be missed due to the use of a factory method? Hmm. I can't immediately think of how, but if you can come up with an example please share. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 16:46:31 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 16:46:31 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Thu, 12 Jan 2023 16:20:12 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 218: >> >>> 216: new TreeScanner() { >>> 217: >>> 218: private Lint lint = ThisEscapeAnalyzer.this.lint; >> >> On a first look I'm not sure about the granularity of suppression here. I believe that suppressing at the class level, or at the constructor level is enough. Allowing to further annotate var declarations and non-constructor methods, while doable, might actually be counter productive - in the sense that the annotation does not occur in the constructor (where you'd want to see it) but in some other method. I think the fact that a constructor is escaping (willingly) should be a visible thing. Something to consider. > > Two things... > > We need to support annotations on field declarations because their initializers are effectively mini-constructors. But we don't need it on local variables, parameters, etc. - too confusing. > > For annotations on methods, yes it's debatable. It can be handy if you have e.g. an `init()` method that all of your constructors invoke. However, I agree it's also confusing, so I will remove. > > But we should keep the notion that if a constructor invokes `this()`, and the invoked constructor has annotations suppressed, then we skip over the constructor invocation. > > I will make these updates. Yep - I guess there's a general theme of "where do we want the warnings to be reported". My general feeling is that reporting a warning on the constructor might be enough - but I see that you try to generate a warning in the exact spot where the leakage happens - which I'm not sure if it's ok, or too clever. >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 270: >> >>> 268: final boolean analyzable = this.currentClassIsExternallyExtendable() && >>> 269: TreeInfo.isConstructor(tree) && >>> 270: !tree.sym.isPrivate() && >> >> Why aren't private constructors analyzed? If we have a class with a private constructor and public static factory invoking said constructor, and the constructor makes `this` escape, isn't that an issue we should detect? > >> If we have a class with a private constructor and public static factory invoking said constructor, and the constructor makes this escape, isn't that an issue we should detect? > > A static factory method will not create a subclassed instance, so there's no 'this' escape problem. > > But I admit I completely missed factory methods as a potential thing to worry about. > > Is it possible for a leak to be missed due to the use of a factory method? > > Hmm. I can't immediately think of how, but if you can come up with an example please share. I guess what I'm thinking about: class Foo { private Foo() { m(this); } public void m() { ... } // overridable static Foo makeFoo() { return new Foo(); } } >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 294: >> >>> 292: !(this.currentClass.sym.isSealed() && this.currentClass.permitting.isEmpty()) && >>> 293: !(this.currentClass.sym.owner.kind == MTH) && >>> 294: !this.privateOuter; >> >> Here, note that is the owner of the current class symbol is a method, that covers anonymous classes too, which is a part of `privateOuter`. So the only think we need to check here is whether "currentClass" is private, which is a simple predicate. No need to carry `privateOuter` I believe > > Unless you explicitly declare a nested class `private`, it won't have the `ACC_PRIVATE` flag, even though it is "implicitly private" because it has a `private` enclosing class. > > Example: > > $ cat PrivateOuter.java > public class PrivateOuter { > private static class Inner1 { > static class Inner2 { > } > } > } > $ javap -v PrivateOuter$Inner1$Inner2 > Classfile /Users/archie/proj/jdk/flex-test/classes/PrivateOuter$Inner1$Inner2.class > Last modified Jan 12, 2023; size 408 bytes > SHA-256 checksum 51ba6d39a5e66df2a078761d6424acbea7a8e32b8451f6ca7d2af49889673b2c > Compiled from "PrivateOuter.java" > class PrivateOuter$Inner1$Inner2 > minor version: 0 > major version: 63 > flags: (0x0020) ACC_SUPER > this_class: #7 // PrivateOuter$Inner1$Inner2 > super_class: #2 // java/lang/Object > ... > > > So we have to keep track of this "implicit privateness" manually, which is what the `privateOuter` flag is for. D'oh - missed the `|=` - so this keeps updating... ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 16:55:39 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 16:55:39 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 10:48:49 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 227: > >> 225: final boolean privateOuterPrev = this.privateOuter; >> 226: final Lint lintPrev = this.lint; >> 227: this.lint = this.lint.augment(tree.sym); > > general stylistic comment - I see here and everywhere in this class `this.xyz` - this is not the norm in the rest of the javac codebase, and it would be better to replace it with just `xyz` OK. I will reluctantly remove... `` > Why on earth wouldn't you want to make it clear which one of N outer classes a field comes from, and that it's a field, and not a variable declared somewhere off screen?? > > IMHO omitting 'this' qualifiers is effectively accepting the grave offense of code obfuscation in exchange for a tiny smidgen of brevity. > > It's definitely made it harder for me to read and understand the compiler, with all the levels of nesting it has. > `` I readily admit I'm probably in the minority on this and anyway it's a bikeshed thing so there's no point in debating it. I will go with the flow :) though I feel a little sorry for the next person who has to read this code. > From a documentation perspective it might carry a bit of value Yes, that's the purpose - the `final` is for the human viewer, not the compiler. Just trying to be helpful to the next person. But you're right it's inconsistent so I'll remove. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 17:16:34 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 17:16:34 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 10:56:53 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 411: > >> 409: final boolean referenceExpressionNode; >> 410: switch (tree.getTag()) { >> 411: case CASE: > > surprised to see `CASE` here - as that's not an expression I put it there because of switch expressions and `yeild`... ? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Thu Jan 12 17:43:26 2023 From: vromero at openjdk.org (Vicente Romero) Date: Thu, 12 Jan 2023 17:43:26 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: On Wed, 11 Jan 2023 03:30:03 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Use the more appropriate Type comparison method Types.isSameType(). > - Add some more comments to clarify how the analysis works. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 200: > 198: // > 199: > 200: public void analyzeTree(Env env) { nit: this method could be removed in favor of the overloaded version below src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 204: > 202: } > 203: > 204: public void analyzeTree(Env env, JCTree tree) { nit: `env` parameter doesn't seem to be used could be dropped I think ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 17:43:30 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 17:43:30 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 17:13:55 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 411: >> >>> 409: final boolean referenceExpressionNode; >>> 410: switch (tree.getTag()) { >>> 411: case CASE: >> >> surprised to see `CASE` here - as that's not an expression > > I put it there because of switch expressions and `yeild`... ? Well, yield can... yield a value - `case` doesn't. So I'm confused. Also because the variable is called `referenceExpressionNode` and `CASE` is not an expression. Can `CASE` leave anything on the stack? YIELD does, but CASE? >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 454: >> >>> 452: >>> 453: // If the expression type is incompatible with 'this', discard it >>> 454: if (type != null && !this.isSubtype(this.targetClass.sym.type, type)) >> >> Instead of adding the direct reference, and then having to check if the reference needs to be removed, would it be possible not to add the reference in the first place if the types mismatch? > > No because (for example) what if you cast? > > The thing you're casting might be compatible, but after the cast it might become incompatible. Uhm. Turns out I probably did not understand the filter correctly, and now I'm more dubious about what it actually does. Say you have this hierarchy: interface A { } class B { B() { A a = (A)this; ... } } class C extends B implements A { } ``` Pathological case, I know. But the filtering will end up dropping the expression Ref on the floor, right? (because B and A are unrelated). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 17:43:36 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 17:43:36 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 11:09:35 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 444: > >> 442: if (referenceExpressionNode) { >> 443: >> 444: // We treat instance methods as having a "value" equal to their instance > > The comment is slightly misleading - e.g. I'd suggest clarifying "having a "value" whose type is the same as that of the class in which the method is defined" Agreed - will fix. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 454: > >> 452: >> 453: // If the expression type is incompatible with 'this', discard it >> 454: if (type != null && !this.isSubtype(this.targetClass.sym.type, type)) > > Instead of adding the direct reference, and then having to check if the reference needs to be removed, would it be possible not to add the reference in the first place if the types mismatch? No because (for example) what if you cast? The thing you're casting might be compatible, but after the cast it might become incompatible. > This will then determine how to interpret this in the context of that method analysis - e.g. when we see a JCIdent for this, we create a direct/indirect ExprRef based on what the receiver kind was. Correct? Yes, exactly. When we "invoke" a method, we "preload" the set of current references that the method is going to have when it starts. That "preload" step includes any references from (a) the method receiver (non-static methods only) and (b) method parameters. To the extent the method receiver has a direct/indirect reference, that turns into a direct/indirect `ThisRef` during method execution. You can see this happen in the very next lines after what you quoted. But of course the method invocation (the "apply") could have been applied to any arbitrary expression as the receiver. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 817: > >> 815: // Methods - the "value" of a non-static method is a reference to its instance >> 816: final Symbol sym = tree.sym; >> 817: if (sym.kind == MTH) { > > This is perhaps where filtering based on the declaring class could make sense (to avoid having to filter later) ? Perhaps this could also be centralized - e.g. whenever you create an ExprRef you also pass the type for it, and if the type matches that for the current class you create it and add to the list, otherwise you skip it. Yes but see previous comment regarding casting. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 875: > >> 873: // Reference to this? >> 874: if (tree.name == names._this || tree.name == names._super) { >> 875: if (this.refs.contains(ThisRef.direct())) > > This idiom occurs quite a lot. If I'm correct, this basically amounts at asking as to whether the receiver of the method we're currently evaluating is direct or not (which is an invariant, given a method body - e.g. for a given method this "fact" should stay the same). If that's the case, perhaps capturing this in a flag could be better - then you could have just have a single method e.g. `XYZRef.create(boolean direct)`, and remove the branching (here and elsewhere). The code you quoted has nothing specifically to do with method invocations. This code is simply handing the evaluation of the expressions `this` and `super`. For example, `this` could just be a parameter we're passing to another method. When `this` or `super` expressions are evaluated, the thing left on top of the stack is a direct/indirect reference (i.e., an `ExprRef`) exactly when the there is a direct/indirect reference of type `ThisRef` in the current reference set. In cases where `this` is then "invoked", e.g., `this()`, the `ExprRef` (top of Java stack) becomes the method receiver, and when the method is "invoked" it turns back into a `ThisRef` (see earlier question). Regarding the optimization you mention, in light of the above I'm not sure it would still work. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 17:53:25 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 17:53:25 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 12:15:17 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 175: > >> 173: private DiagnosticPosition[] pendingWarning; >> 174: >> 175: // These fields are scoped to the CONSTRUCTOR OR INVOKED METHOD BEING ANALYZED > > Watch out for "all caps" Will fix. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 900: > >> 898: final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; >> 899: final Type methodOwnerType = sym.owner.type; >> 900: if (this.isSubtype(currentClassType, methodOwnerType)) { > > I believe what you need here is not subtyping but subclassing - see `Symbol.isSubclass` Hmm, I tried using `Symbol.isSubclass()` but it caused test failures. Obviously I don't quite know what I'm doing and I'm loathe to break what is already working. Do you have a suggested patch? > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 909: > >> 907: >> 908: // Check for implicit outer 'this' reference >> 909: if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { > > Similarly here - look for `Symbol.isEnclosedBy` Same comment as previous: I don't quite know what I'm doing and I'm loathe to break what is already working. Do you have a suggested patch? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 18:00:36 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 18:00:36 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 12:17:32 GMT, Maurizio Cimadamore wrote: > There is a concept of push/popScope and then there's a separate concept of call stack (which is just a list of diagnostic position up to the point). I wonder if this could be better modeled by using a single class e.g. Scope/Frame which has a diagnostic position, plus other useful things. I think that would be more confusing, because they're really two different animals. Scopes only have meaning within a single method. They simply serve to bracket the lifetimes of `VarRef` references, following Java curly brace scope. When you "invoke" a method, you put aside the current stack of scopes and start over with an empty scope stack. They don't bridge between methods. Call stacks are just a list of method+code position therein, and they exist outside of any single method. They have nothing to do with Java scopes defined by curly braces. > Perhaps it might even be helpful to have a ref set on each scope, so that you don't have to attach a "depth" to each ref - the depth of the ref would be determined by the "scope" in which it appears. That's another way to skin the same cat... in fact I had a design like that before but then realized it was a lot simpler to just carry around one `RefSet`. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 18:09:27 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 18:09:27 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 12:26:27 GMT, Maurizio Cimadamore wrote: > Do we really need a set for this? There are surely other ways to model things. But I got myself really confused trying to build more complicated models. What I ended up with is this simple model that works: * There is a set of `Ref` subclasses that model the various types of 'this' references possible: `OuterRef`, `ExprRef`, etc. * There is a singleton `this.refs`, which just is a `Set`, containing the 'this' references that are alive at the current moment * As we "execute" code, all we need to do is update the `this.refs` based on what the current bit of code does E.g.... When a variable is assigned a value that has a reference, we add a `VarRef` for that variable. When we leave a scope, we remove any `Ref`'s that are no longer in scope. Before executing a method, we add `Ref`'s for the method receiver and parameter. When we return from a non-void method, we convert any `ReturnRef` into a `ExprRef`. Etc. THAT I can understand. I don't see converting the above into a bitmap or whatever as worth the additional complexity. We're not programming in perl here. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 18:16:25 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 18:16:25 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: Message-ID: <1r69eKftXv6ZlGQP76mNrfgbldbDcMxhnyVOQ8oUV7U=.8facaf51-1f7e-486a-912e-a9a5912b7d88@github.com> On Thu, 12 Jan 2023 17:39:05 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Use the more appropriate Type comparison method Types.isSameType(). >> - Add some more comments to clarify how the analysis works. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 200: > >> 198: // >> 199: >> 200: public void analyzeTree(Env env) { > > nit: this method could be removed in favor of the overloaded version below Thanks - will fix. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 204: > >> 202: } >> 203: >> 204: public void analyzeTree(Env env, JCTree tree) { > > nit: `env` parameter doesn't seem to be used could be dropped I think Thanks - will fix. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 18:16:27 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 18:16:27 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 17:48:37 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 909: >> >>> 907: >>> 908: // Check for implicit outer 'this' reference >>> 909: if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { >> >> Similarly here - look for `Symbol.isEnclosedBy` > > Same comment as previous: I don't quite know what I'm doing and I'm loathe to break what is already working. Do you have a suggested patch? I can't seem to be able to run tests - I get failures in the build: * For target support_test_micro_tools-classes__the.BUILD_INDIFY_batch: ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 18:16:31 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 18:16:31 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 12:28:12 GMT, Maurizio Cimadamore wrote: > This might also be related with the fact that we deal with return values in different ways than with e.g. values returned from a nested scope (where we just pop, and then copy all pending expression to the outer depth). Yes, a method return value that represents a reference is an `ExprRef` just before the `return` is actually executed, but then it turns into a `ReturnRef`. A `ReturnRef` is really just a yellow sticky note that reminds us "Hey whenever you finish 'executing' this method, remember that there is a reference in its return value". > This might also be related with the fact that we deal with return values in different ways than with e.g. values returned from a nested scope (where we just pop, and then copy all pending expression to the outer depth). Exactly. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 18:21:22 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 18:21:22 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: <1vfnyE9dnZELUp1To60nQYEUIre7g5pcfXHKKHOug0I=.9af24b57-2627-45d8-a7cc-1b4235e99237@github.com> On Thu, 12 Jan 2023 18:11:01 GMT, Maurizio Cimadamore wrote: >> Same comment as previous: I don't quite know what I'm doing and I'm loathe to break what is already working. Do you have a suggested patch? > > I can't seem to be able to run tests - I get failures in the build: > > > * For target support_test_micro_tools-classes__the.BUILD_INDIFY_batch: This patch: diff --git a/make/test/BuildMicrobenchmark.gmk b/make/test/BuildMicrobenchmark.gmk index 1c89328a388..7c3f0293edc 100644 --- a/make/test/BuildMicrobenchmark.gmk +++ b/make/test/BuildMicrobenchmark.gmk @@ -76,7 +76,7 @@ $(eval $(call SetupJavaCompilation, BUILD_INDIFY, \ TARGET_RELEASE := $(TARGET_RELEASE_BOOTJDK), \ SRC := $(TOPDIR)/test/jdk/java/lang/invoke, \ INCLUDE_FILES := indify/Indify.java, \ - DISABLED_WARNINGS := rawtypes serial options, \ + DISABLED_WARNINGS := this-escape rawtypes serial options, \ BIN := $(MICROBENCHMARK_TOOLS_CLASSES), \ JAVAC_FLAGS := -XDstringConcat=inline -Xprefer:newer, \ )) @@ -91,7 +91,7 @@ $(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \ TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \ SMALL_JAVA := false, \ CLASSPATH := $(MICROBENCHMARK_CLASSPATH), \ - DISABLED_WARNINGS := processing rawtypes cast serial preview, \ + DISABLED_WARNINGS := this-escape processing rawtypes cast serial preview, \ SRC := $(MICROBENCHMARK_SRC), \ BIN := $(MICROBENCHMARK_CLASSES), \ JAVAC_FLAGS := --add-exports java.base/sun.security.util=ALL-UNNAMED \ diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java index 9d35c2fbc0a..4e2b1e558e7 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java @@ -897,6 +897,7 @@ class ThisEscapeAnalyzer extends TreeScanner { // Check for implicit 'this' reference final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; final Type methodOwnerType = sym.owner.type; + //if (currentClassType.tsym.isSubClass(sym.owner, types)) { if (this.isSubtype(currentClassType, methodOwnerType)) { if (this.refs.contains(ThisRef.direct())) this.refs.add(ExprRef.direct(this.depth)); @@ -906,6 +907,7 @@ class ThisEscapeAnalyzer extends TreeScanner { } // Check for implicit outer 'this' reference + // if (currentClassType.tsym.isEnclosedBy((ClassSymbol)sym.owner)) { if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { if (this.refs.contains(OuterRef.direct())) this.refs.add(ExprRef.direct(this.depth)); Fixes the build failure. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 18:40:28 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 18:40:28 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Thu, 12 Jan 2023 16:40:33 GMT, Maurizio Cimadamore wrote: > I guess what I'm thinking about: No leak is possible in that example. * `new Foo()` creates an instance of `Foo` (not a subclass of `Foo`) therefore `m()` is not overridden * Any subclass of `Foo` that may exist in the outside world cannot use the `Foo()` constructor that leaks because it's private ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 18:43:21 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 18:43:21 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: <1vfnyE9dnZELUp1To60nQYEUIre7g5pcfXHKKHOug0I=.9af24b57-2627-45d8-a7cc-1b4235e99237@github.com> References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <1vfnyE9dnZELUp1To60nQYEUIre7g5pcfXHKKHOug0I=.9af24b57-2627-45d8-a7cc-1b4235e99237@github.com> Message-ID: On Thu, 12 Jan 2023 18:18:38 GMT, Maurizio Cimadamore wrote: >> I can't seem to be able to run tests - I get failures in the build: >> >> >> * For target support_test_micro_tools-classes__the.BUILD_INDIFY_batch: > > This patch: > > > diff --git a/make/test/BuildMicrobenchmark.gmk b/make/test/BuildMicrobenchmark.gmk > index 1c89328a388..7c3f0293edc 100644 > --- a/make/test/BuildMicrobenchmark.gmk > +++ b/make/test/BuildMicrobenchmark.gmk > @@ -76,7 +76,7 @@ $(eval $(call SetupJavaCompilation, BUILD_INDIFY, \ > TARGET_RELEASE := $(TARGET_RELEASE_BOOTJDK), \ > SRC := $(TOPDIR)/test/jdk/java/lang/invoke, \ > INCLUDE_FILES := indify/Indify.java, \ > - DISABLED_WARNINGS := rawtypes serial options, \ > + DISABLED_WARNINGS := this-escape rawtypes serial options, \ > BIN := $(MICROBENCHMARK_TOOLS_CLASSES), \ > JAVAC_FLAGS := -XDstringConcat=inline -Xprefer:newer, \ > )) > @@ -91,7 +91,7 @@ $(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \ > TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \ > SMALL_JAVA := false, \ > CLASSPATH := $(MICROBENCHMARK_CLASSPATH), \ > - DISABLED_WARNINGS := processing rawtypes cast serial preview, \ > + DISABLED_WARNINGS := this-escape processing rawtypes cast serial preview, \ > SRC := $(MICROBENCHMARK_SRC), \ > BIN := $(MICROBENCHMARK_CLASSES), \ > JAVAC_FLAGS := --add-exports java.base/sun.security.util=ALL-UNNAMED \ > diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java > index 9d35c2fbc0a..4e2b1e558e7 100644 > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java > @@ -897,6 +897,7 @@ class ThisEscapeAnalyzer extends TreeScanner { > // Check for implicit 'this' reference > final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; > final Type methodOwnerType = sym.owner.type; > + //if (currentClassType.tsym.isSubClass(sym.owner, types)) { > if (this.isSubtype(currentClassType, methodOwnerType)) { > if (this.refs.contains(ThisRef.direct())) > this.refs.add(ExprRef.direct(this.depth)); > @@ -906,6 +907,7 @@ class ThisEscapeAnalyzer extends TreeScanner { > } > > // Check for implicit outer 'this' reference > + // if (currentClassType.tsym.isEnclosedBy((ClassSymbol)sym.owner)) { > if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { > if (this.refs.contains(OuterRef.direct())) > this.refs.add(ExprRef.direct(this.depth)); > > > Fixes the build failure. This patch passes all tests: diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java index 9d35c2fbc0a..e755c54d0c8 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java @@ -451,7 +451,7 @@ class ThisEscapeAnalyzer extends TreeScanner { } // If the expression type is incompatible with 'this', discard it - if (type != null && !this.isSubtype(this.targetClass.sym.type, type)) + if (type != null && !this.targetClass.sym.isSubClass(type.tsym, types)) this.refs.remove(ExprRef.direct(this.depth)); } } @@ -672,7 +672,7 @@ class ThisEscapeAnalyzer extends TreeScanner { if (explicitOuterThis != null) { this.scan(explicitOuterThis); this.refs.removeExprs(this.depth, direct -> outerRefs.add(new OuterRef(direct))); - } else if (this.types.hasOuterClass(type, this.methodClass.type)) { + } else if (type.tsym.isEnclosedBy(this.methodClass.sym)) { if (this.refs.contains(ThisRef.direct())) outerRefs.add(OuterRef.direct()); if (this.refs.contains(ThisRef.indirect())) @@ -801,9 +801,8 @@ class ThisEscapeAnalyzer extends TreeScanner { // Explicit outer 'this' reference? final Type selectedType = this.types.erasure(tree.selected.type); if (selectedType.hasTag(CLASS)) { - final Type.ClassType selectedClassType = (Type.ClassType)selectedType; if (tree.name == this.names._this && - this.types.hasOuterClass(currentClassType, selectedClassType)) { + currentClassType.tsym.isEnclosedBy((ClassSymbol)selectedType.tsym)) { if (this.refs.contains(OuterRef.direct())) this.refs.add(ExprRef.direct(this.depth)); if (this.refs.contains(OuterRef.indirect())) @@ -895,9 +894,7 @@ class ThisEscapeAnalyzer extends TreeScanner { final MethodSymbol sym = (MethodSymbol)tree.sym; // Check for implicit 'this' reference - final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; - final Type methodOwnerType = sym.owner.type; - if (this.isSubtype(currentClassType, methodOwnerType)) { + if (methodClass.sym.isSubClass(sym.owner, types)) { if (this.refs.contains(ThisRef.direct())) this.refs.add(ExprRef.direct(this.depth)); if (this.refs.contains(ThisRef.indirect())) @@ -906,7 +903,7 @@ class ThisEscapeAnalyzer extends TreeScanner { } // Check for implicit outer 'this' reference - if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { + if (methodClass.sym.isEnclosedBy((ClassSymbol)sym.owner)) { if (this.refs.contains(OuterRef.direct())) this.refs.add(ExprRef.direct(this.depth)); Btw, I believe a similar trick can be used in TreeInfo.isExplicitThisReference. If I'm correct, `hasOuterClass` should probably be removed as it duplicates already existing functionality. Since I'm bringing this up, as TreeInfo.isExplicitThisReference is only used by the new analyzer, it would be cleaner if it was defined there, at least until it's clear it might be needed by some other client. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 18:51:33 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 18:51:33 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Thu, 12 Jan 2023 18:37:06 GMT, Archie L. Cobbs wrote: >> I guess what I'm thinking about: >> >> class Foo { >> private Foo() { >> m(this); >> } >> >> public void m() { ... } // overridable >> >> static Foo makeFoo() { return new Foo(); } >> } > >> I guess what I'm thinking about: > > No leak is possible in that example. > * `new Foo()` creates an instance of `Foo` (not a subclass of `Foo`) therefore `m()` is not overridden > * Any subclass of `Foo` that may exist in the outside world cannot use the `Foo()` constructor that leaks because it's private but what if `m` is a static method in a separate compilation unit? Should it be able to observe a partially initialized Foo? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 19:04:22 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 19:04:22 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 17:29:22 GMT, Maurizio Cimadamore wrote: >> I put it there because of switch expressions and `yeild`... ? > > Well, yield can... yield a value - `case` doesn't. So I'm confused. Also because the variable is called `referenceExpressionNode` and `CASE` is not an expression. Can `CASE` leave anything on the stack? YIELD does, but CASE? It's just an artifact of the way switch expressions are handled: @Override public void visitSwitchExpression(JCSwitchExpression tree) { visitScoped(tree, true, t -> { scan(t.selector); refs.discardExprs(depth); RefSet combinedRefs = new RefSet<>(); for (List cases = t.cases; cases.nonEmpty(); cases = cases.tail) { scan(cases.head); combinedRefs.addAll(refs.removeExprs(depth)); } refs.addAll(combinedRefs); }); } @Override public void visitCase(JCCase tree) { scan(tree.stats); // no need to scan labels } After scanning a switch expression case, the `yield`'ed value will be on the top of the stack. Then `visitCase` does NOT remove it, so that it can be picked up and removed by `visitSwitchExpression()`. But this can be cleaned up a little bit, by having `visitSwitchExpression()` not delegate to `visitCase()` but rather iterate through the case statements itself directly. Then we can remove the `CASE` as you suggest. Also I realized we need to handle `yield`'ed values like `return` values, i.e., collect and remember them until the entire case is complete. I'll fix. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 19:04:25 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 19:04:25 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 17:33:48 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 875: >> >>> 873: // Reference to this? >>> 874: if (tree.name == names._this || tree.name == names._super) { >>> 875: if (this.refs.contains(ThisRef.direct())) >> >> This idiom occurs quite a lot. If I'm correct, this basically amounts at asking as to whether the receiver of the method we're currently evaluating is direct or not (which is an invariant, given a method body - e.g. for a given method this "fact" should stay the same). If that's the case, perhaps capturing this in a flag could be better - then you could have just have a single method e.g. `XYZRef.create(boolean direct)`, and remove the branching (here and elsewhere). > > The code you quoted has nothing specifically to do with method invocations. This code is simply handing the evaluation of the expressions `this` and `super`. For example, `this` could just be a parameter we're passing to another method. > > When `this` or `super` expressions are evaluated, the thing left on top of the stack is a direct/indirect reference (i.e., an `ExprRef`) exactly when the there is a direct/indirect reference of type `ThisRef` in the current reference set. > > In cases where `this` is then "invoked", e.g., `this()`, the `ExprRef` (top of Java stack) becomes the method receiver, and when the method is "invoked" it turns back into a `ThisRef` (see earlier question). > > Regarding the optimization you mention, in light of the above I'm not sure it would still work. My point is about who puts ThisRef in the set to begin with. It seems to me that ThisRef is put there at the start of a method analysis. After which, there's several code points where we say "if there's a direct ThisRef in the set, do this, otherwise, if there's an indirect ThisRef in the set, do that". But the ThisRef (whether indirect or direct) seems set once and for all (when we start the analysis, and then inside visitApply). There is also this bit in `visitReference`: case SUPER: if (this.refs.contains(ThisRef.direct())) receiverRefs.add(ThisRef.direct()); if (this.refs.contains(ThisRef.indirect())) receiverRefs.add(ThisRef.indirect()); break; But this doesn't change what I'm saying - there seems to be a general property when we execute this analysis which says whether the current execution context has a direct `this` or not. This seems to me better captured with a boolean, which is then fed back to all the other various downstream ref creation. The main observation, at least for me, is that the code unifies everything under refs, when in reality there are different aspects: * the set of variables that can point to this, whether directly or indirectly (this is truly a set) * whether the current context has a direct or indirect this (this seems more a flag to me) * whether the expression on top of stack is direct/indirect this reference or not (again, 3 possible values here) - but granted, there `depth` here to take into account, so you probably end up with a set (given that we don't want to model a scope with its own set) When reading the code, seeing set expression like containment checks or removals for things that doesn't seem to be truly sets (unless I'm missing something) was genuinely confusing me. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 19:15:20 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 19:15:20 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 17:40:36 GMT, Maurizio Cimadamore wrote: > But the filtering will end up dropping the expression Ref on the floor, right? (because B and A are unrelated). Ah, I see what you mean. Here's a more complete example: public class CastLeak { public CastLeak() { ((CastLeak)(Runnable)this).mightLeak(); } public void mightLeak() { } } That would be a leak for any subclass that implements `Runnable`. Yet no warning is generated. So the filtering by expression type is going to potentially create false negatives. But it also eliminates a bunch of false positives. And the false negatives are probably all somewhat pathological like the example above. So I still think it's worth doing. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 19:27:24 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 19:27:24 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <1vfnyE9dnZELUp1To60nQYEUIre7g5pcfXHKKHOug0I=.9af24b57-2627-45d8-a7cc-1b4235e99237@github.com> Message-ID: On Thu, 12 Jan 2023 18:40:38 GMT, Maurizio Cimadamore wrote: >> This patch: >> >> >> diff --git a/make/test/BuildMicrobenchmark.gmk b/make/test/BuildMicrobenchmark.gmk >> index 1c89328a388..7c3f0293edc 100644 >> --- a/make/test/BuildMicrobenchmark.gmk >> +++ b/make/test/BuildMicrobenchmark.gmk >> @@ -76,7 +76,7 @@ $(eval $(call SetupJavaCompilation, BUILD_INDIFY, \ >> TARGET_RELEASE := $(TARGET_RELEASE_BOOTJDK), \ >> SRC := $(TOPDIR)/test/jdk/java/lang/invoke, \ >> INCLUDE_FILES := indify/Indify.java, \ >> - DISABLED_WARNINGS := rawtypes serial options, \ >> + DISABLED_WARNINGS := this-escape rawtypes serial options, \ >> BIN := $(MICROBENCHMARK_TOOLS_CLASSES), \ >> JAVAC_FLAGS := -XDstringConcat=inline -Xprefer:newer, \ >> )) >> @@ -91,7 +91,7 @@ $(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \ >> TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \ >> SMALL_JAVA := false, \ >> CLASSPATH := $(MICROBENCHMARK_CLASSPATH), \ >> - DISABLED_WARNINGS := processing rawtypes cast serial preview, \ >> + DISABLED_WARNINGS := this-escape processing rawtypes cast serial preview, \ >> SRC := $(MICROBENCHMARK_SRC), \ >> BIN := $(MICROBENCHMARK_CLASSES), \ >> JAVAC_FLAGS := --add-exports java.base/sun.security.util=ALL-UNNAMED \ >> diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java >> index 9d35c2fbc0a..4e2b1e558e7 100644 >> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java >> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java >> @@ -897,6 +897,7 @@ class ThisEscapeAnalyzer extends TreeScanner { >> // Check for implicit 'this' reference >> final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; >> final Type methodOwnerType = sym.owner.type; >> + //if (currentClassType.tsym.isSubClass(sym.owner, types)) { >> if (this.isSubtype(currentClassType, methodOwnerType)) { >> if (this.refs.contains(ThisRef.direct())) >> this.refs.add(ExprRef.direct(this.depth)); >> @@ -906,6 +907,7 @@ class ThisEscapeAnalyzer extends TreeScanner { >> } >> >> // Check for implicit outer 'this' reference >> + // if (currentClassType.tsym.isEnclosedBy((ClassSymbol)sym.owner)) { >> if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { >> if (this.refs.contains(OuterRef.direct())) >> this.refs.add(ExprRef.direct(this.depth)); >> >> >> Fixes the build failure. > > This patch passes all tests: > > > diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java > index 9d35c2fbc0a..e755c54d0c8 100644 > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java > @@ -451,7 +451,7 @@ class ThisEscapeAnalyzer extends TreeScanner { > } > > // If the expression type is incompatible with 'this', discard it > - if (type != null && !this.isSubtype(this.targetClass.sym.type, type)) > + if (type != null && !this.targetClass.sym.isSubClass(type.tsym, types)) > this.refs.remove(ExprRef.direct(this.depth)); > } > } > @@ -672,7 +672,7 @@ class ThisEscapeAnalyzer extends TreeScanner { > if (explicitOuterThis != null) { > this.scan(explicitOuterThis); > this.refs.removeExprs(this.depth, direct -> outerRefs.add(new OuterRef(direct))); > - } else if (this.types.hasOuterClass(type, this.methodClass.type)) { > + } else if (type.tsym.isEnclosedBy(this.methodClass.sym)) { > if (this.refs.contains(ThisRef.direct())) > outerRefs.add(OuterRef.direct()); > if (this.refs.contains(ThisRef.indirect())) > @@ -801,9 +801,8 @@ class ThisEscapeAnalyzer extends TreeScanner { > // Explicit outer 'this' reference? > final Type selectedType = this.types.erasure(tree.selected.type); > if (selectedType.hasTag(CLASS)) { > - final Type.ClassType selectedClassType = (Type.ClassType)selectedType; > if (tree.name == this.names._this && > - this.types.hasOuterClass(currentClassType, selectedClassType)) { > + currentClassType.tsym.isEnclosedBy((ClassSymbol)selectedType.tsym)) { > if (this.refs.contains(OuterRef.direct())) > this.refs.add(ExprRef.direct(this.depth)); > if (this.refs.contains(OuterRef.indirect())) > @@ -895,9 +894,7 @@ class ThisEscapeAnalyzer extends TreeScanner { > final MethodSymbol sym = (MethodSymbol)tree.sym; > > // Check for implicit 'this' reference > - final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; > - final Type methodOwnerType = sym.owner.type; > - if (this.isSubtype(currentClassType, methodOwnerType)) { > + if (methodClass.sym.isSubClass(sym.owner, types)) { > if (this.refs.contains(ThisRef.direct())) > this.refs.add(ExprRef.direct(this.depth)); > if (this.refs.contains(ThisRef.indirect())) > @@ -906,7 +903,7 @@ class ThisEscapeAnalyzer extends TreeScanner { > } > > // Check for implicit outer 'this' reference > - if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { > + if (methodClass.sym.isEnclosedBy((ClassSymbol)sym.owner)) { > if (this.refs.contains(OuterRef.direct())) > this.refs.add(ExprRef.direct(this.depth)); > > > Btw, I believe a similar trick can be used in TreeInfo.isExplicitThisReference. If I'm correct, `hasOuterClass` should probably be removed as it duplicates already existing functionality. > > Since I'm bringing this up, as TreeInfo.isExplicitThisReference is only used by the new analyzer, it would be cleaner if it was defined there, at least until it's clear it might be needed by some other client. Weird. I don't get that build failure. Neither does github... I have been relying on the github build "Actions" succeeding to determine if "the build works" and according to that it is building. I will add the `DISABLED_WARNINGS` in any case. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 21:07:28 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 21:07:28 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Thu, 12 Jan 2023 18:48:25 GMT, Maurizio Cimadamore wrote: >>> I guess what I'm thinking about: >> >> No leak is possible in that example. >> * `new Foo()` creates an instance of `Foo` (not a subclass of `Foo`) therefore `m()` is not overridden >> * Any subclass of `Foo` that may exist in the outside world cannot use the `Foo()` constructor that leaks because it's private > > but what if `m` is a static method in a separate compilation unit? Should it be able to observe a partially initialized Foo? Caring about the proper initialization of any class in the _current_ compilation unit is an explicit non-goal. We only care about bugs where a superclass and subclass are in separate compilation units. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 21:07:30 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 21:07:30 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <1vfnyE9dnZELUp1To60nQYEUIre7g5pcfXHKKHOug0I=.9af24b57-2627-45d8-a7cc-1b4235e99237@github.com> Message-ID: On Thu, 12 Jan 2023 19:24:50 GMT, Archie L. Cobbs wrote: >> This patch passes all tests: >> >> >> diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java >> index 9d35c2fbc0a..e755c54d0c8 100644 >> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java >> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java >> @@ -451,7 +451,7 @@ class ThisEscapeAnalyzer extends TreeScanner { >> } >> >> // If the expression type is incompatible with 'this', discard it >> - if (type != null && !this.isSubtype(this.targetClass.sym.type, type)) >> + if (type != null && !this.targetClass.sym.isSubClass(type.tsym, types)) >> this.refs.remove(ExprRef.direct(this.depth)); >> } >> } >> @@ -672,7 +672,7 @@ class ThisEscapeAnalyzer extends TreeScanner { >> if (explicitOuterThis != null) { >> this.scan(explicitOuterThis); >> this.refs.removeExprs(this.depth, direct -> outerRefs.add(new OuterRef(direct))); >> - } else if (this.types.hasOuterClass(type, this.methodClass.type)) { >> + } else if (type.tsym.isEnclosedBy(this.methodClass.sym)) { >> if (this.refs.contains(ThisRef.direct())) >> outerRefs.add(OuterRef.direct()); >> if (this.refs.contains(ThisRef.indirect())) >> @@ -801,9 +801,8 @@ class ThisEscapeAnalyzer extends TreeScanner { >> // Explicit outer 'this' reference? >> final Type selectedType = this.types.erasure(tree.selected.type); >> if (selectedType.hasTag(CLASS)) { >> - final Type.ClassType selectedClassType = (Type.ClassType)selectedType; >> if (tree.name == this.names._this && >> - this.types.hasOuterClass(currentClassType, selectedClassType)) { >> + currentClassType.tsym.isEnclosedBy((ClassSymbol)selectedType.tsym)) { >> if (this.refs.contains(OuterRef.direct())) >> this.refs.add(ExprRef.direct(this.depth)); >> if (this.refs.contains(OuterRef.indirect())) >> @@ -895,9 +894,7 @@ class ThisEscapeAnalyzer extends TreeScanner { >> final MethodSymbol sym = (MethodSymbol)tree.sym; >> >> // Check for implicit 'this' reference >> - final Type.ClassType currentClassType = (Type.ClassType)this.methodClass.sym.type; >> - final Type methodOwnerType = sym.owner.type; >> - if (this.isSubtype(currentClassType, methodOwnerType)) { >> + if (methodClass.sym.isSubClass(sym.owner, types)) { >> if (this.refs.contains(ThisRef.direct())) >> this.refs.add(ExprRef.direct(this.depth)); >> if (this.refs.contains(ThisRef.indirect())) >> @@ -906,7 +903,7 @@ class ThisEscapeAnalyzer extends TreeScanner { >> } >> >> // Check for implicit outer 'this' reference >> - if (this.types.hasOuterClass(currentClassType, methodOwnerType)) { >> + if (methodClass.sym.isEnclosedBy((ClassSymbol)sym.owner)) { >> if (this.refs.contains(OuterRef.direct())) >> this.refs.add(ExprRef.direct(this.depth)); >> >> >> Btw, I believe a similar trick can be used in TreeInfo.isExplicitThisReference. If I'm correct, `hasOuterClass` should probably be removed as it duplicates already existing functionality. >> >> Since I'm bringing this up, as TreeInfo.isExplicitThisReference is only used by the new analyzer, it would be cleaner if it was defined there, at least until it's clear it might be needed by some other client. > > Weird. I don't get that build failure. > > Neither does github... I have been relying on the github build "Actions" succeeding to determine if "the build works" and according to that it is building. > > I will add the `DISABLED_WARNINGS` in any case. Thanks for the patch! The semantics of `hasOuterClass()` returns false if A and B are the same class, while `isEnclosedBy()` returns true if A and B are the same class. However, I don't think it would actually matter in practice... Regardless, I'll add the extra equality comparison and apply your patch and also the suggestions to integrate `isExplicitThisReference()` and eliminate `hasOuterClass()`. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Thu Jan 12 21:31:25 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Thu, 12 Jan 2023 21:31:25 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 19:01:10 GMT, Maurizio Cimadamore wrote: >> The code you quoted has nothing specifically to do with method invocations. This code is simply handing the evaluation of the expressions `this` and `super`. For example, `this` could just be a parameter we're passing to another method. >> >> When `this` or `super` expressions are evaluated, the thing left on top of the stack is a direct/indirect reference (i.e., an `ExprRef`) exactly when the there is a direct/indirect reference of type `ThisRef` in the current reference set. >> >> In cases where `this` is then "invoked", e.g., `this()`, the `ExprRef` (top of Java stack) becomes the method receiver, and when the method is "invoked" it turns back into a `ThisRef` (see earlier question). >> >> Regarding the optimization you mention, in light of the above I'm not sure it would still work. > > My point is about who puts ThisRef in the set to begin with. It seems to me that ThisRef is put there at the start of a method analysis. After which, there's several code points where we say "if there's a direct ThisRef in the set, do this, otherwise, if there's an indirect ThisRef in the set, do that". But the ThisRef (whether indirect or direct) seems set once and for all (when we start the analysis, and then inside visitApply). > > There is also this bit in `visitReference`: > > > case SUPER: > if (this.refs.contains(ThisRef.direct())) > receiverRefs.add(ThisRef.direct()); > if (this.refs.contains(ThisRef.indirect())) > receiverRefs.add(ThisRef.indirect()); > break; > > > But this doesn't change what I'm saying - there seems to be a general property when we execute this analysis which says whether the current execution context has a direct `this` or not. This seems to me better captured with a boolean, which is then fed back to all the other various downstream ref creation. > > The main observation, at least for me, is that the code unifies everything under refs, when in reality there are different aspects: > > * the set of variables that can point to this, whether directly or indirectly (this is truly a set) > * whether the current context has a direct or indirect this (this seems more a flag to me) > * whether the expression on top of stack is direct/indirect this reference or not (again, 3 possible values here) - but granted, there `depth` here to take into account, so you probably end up with a set (given that we don't want to model a scope with its own set) > > When reading the code, seeing set expression like containment checks or removals for things that doesn't seem to be truly sets (unless I'm missing something) was genuinely confusing me. I get what you're saying - it seems silly to model what is essentially a fixed, boolean property with the membership of a singleton in a set field, rather than with a simple boolean field. There is a conceptual trade-off though... a lot of the code relates to converting `Ref`'s from one type to another. For example, as pointed out above, a method invocation might convert a `ExprRef` to a `ThisRef`, then to a `ReturnRef`'s, etc. Having these things all be considered part of the same family helps conceptually. The fact that a direct `ThisRef` is a singleton is just a coincidence in this way of looking at things. The benefit is the simplicity of being able to think of the data model as "just a set of references". For example, methods like `RefSet.replaceExprs()` become less elegant (or basically impossible) if there have to be special cases for each type of reference, whereas currently we can do clean stuff like this: @Override public void visitReturn(JCReturn tree) { scan(tree.expr); refs.replaceExprs(depth, ReturnRef::new); } But I'm also realizing now that several places can be cleaned up by taking this event further. E.g., we should replace this code: if (refs.contains(ThisRef.direct())) outerRefs.add(OuterRef.direct()); if (refs.contains(ThisRef.indirect())) outerRefs.add(OuterRef.indirect()); with something like this: refs.mapInto(outerRefs, ThisRef.class, OuterRef::new); I will go through and refactor to do that and clean things up a little more. > When reading the code, seeing set expression like containment checks or removals for things that doesn't seem to be truly sets (unless I'm missing something) was genuinely confusing me. Probably my fault for not providing better documentation of the overall "set of references" conceptual approach. FWIW I added a little bit more in f83a9cf0. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Thu Jan 12 21:47:24 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Thu, 12 Jan 2023 21:47:24 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 21:28:12 GMT, Archie L. Cobbs wrote: >> My point is about who puts ThisRef in the set to begin with. It seems to me that ThisRef is put there at the start of a method analysis. After which, there's several code points where we say "if there's a direct ThisRef in the set, do this, otherwise, if there's an indirect ThisRef in the set, do that". But the ThisRef (whether indirect or direct) seems set once and for all (when we start the analysis, and then inside visitApply). >> >> There is also this bit in `visitReference`: >> >> >> case SUPER: >> if (this.refs.contains(ThisRef.direct())) >> receiverRefs.add(ThisRef.direct()); >> if (this.refs.contains(ThisRef.indirect())) >> receiverRefs.add(ThisRef.indirect()); >> break; >> >> >> But this doesn't change what I'm saying - there seems to be a general property when we execute this analysis which says whether the current execution context has a direct `this` or not. This seems to me better captured with a boolean, which is then fed back to all the other various downstream ref creation. >> >> The main observation, at least for me, is that the code unifies everything under refs, when in reality there are different aspects: >> >> * the set of variables that can point to this, whether directly or indirectly (this is truly a set) >> * whether the current context has a direct or indirect this (this seems more a flag to me) >> * whether the expression on top of stack is direct/indirect this reference or not (again, 3 possible values here) - but granted, there `depth` here to take into account, so you probably end up with a set (given that we don't want to model a scope with its own set) >> >> When reading the code, seeing set expression like containment checks or removals for things that doesn't seem to be truly sets (unless I'm missing something) was genuinely confusing me. > > I get what you're saying - it seems silly to model what is essentially a fixed, boolean property with the membership of a singleton in a set field, rather than with a simple boolean field. > > There is a conceptual trade-off though... a lot of the code relates to converting `Ref`'s from one type to another. For example, as pointed out above, a method invocation might convert a `ExprRef` to a `ThisRef`, then to a `ReturnRef`'s, etc. Having these things all be considered part of the same family helps conceptually. The fact that a direct `ThisRef` is a singleton is just a coincidence in this way of looking at things. > > The benefit is the simplicity of being able to think of the data model as "just a set of references". > > For example, methods like `RefSet.replaceExprs()` become less elegant (or basically impossible) if there have to be special cases for each type of reference, whereas currently we can do clean stuff like this: > > > @Override > public void visitReturn(JCReturn tree) { > scan(tree.expr); > refs.replaceExprs(depth, ReturnRef::new); > } > > > But I'm also realizing now that several places can be cleaned up by taking this event further. E.g., we should replace this code: > > if (refs.contains(ThisRef.direct())) > outerRefs.add(OuterRef.direct()); > if (refs.contains(ThisRef.indirect())) > outerRefs.add(OuterRef.indirect()); > > with something like this: > > refs.mapInto(outerRefs, ThisRef.class, OuterRef::new); > > > I will go through and refactor to do that and clean things up a little more. > >> When reading the code, seeing set expression like containment checks or removals for things that doesn't seem to be truly sets (unless I'm missing something) was genuinely confusing me. > > Probably my fault for not providing better documentation of the overall "set of references" conceptual approach. FWIW I added a little bit more in f83a9cf0. > ```java > ```java > if (refs.contains(ThisRef.direct())) > outerRefs.add(OuterRef.direct()); > if (refs.contains(ThisRef.indirect())) > outerRefs.add(OuterRef.indirect()); > ``` > > > > > > > > > > > > with something like this: > ```java > refs.mapInto(outerRefs, ThisRef.class, OuterRef::new); > ``` > ``` This sounds like a good idea, that idiom is quite widespread, so it should help avoiding repetition. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 04:04:36 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 04:04:36 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with 16 additional commits since the last revision: - Fix bug where all but the last yeild statement were being ignored. - Add method RefSet.mapInto() and use to refactor/clean up. - Fix possible assertion failure when handling if statements. - Use Symbol methods isSubClass() and isEnclosedBy() instead of homebrew stuff. Suggested-by: mcimadamore - Add comment regarding limitations of expresison type filtering. - Add a few more DISABLED_WARNINGS to unbreak build. - Clean up handling of switch expressions a bit. - Remove unused method variant of analyzeTree(). - Avoid all caps in comments. - Clarify confusing comment. - ... and 6 more: https://git.openjdk.org/jdk/compare/6e96a7d7...edf3c3f5 ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/6e96a7d7..edf3c3f5 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=07 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=06-07 Stats: 540 lines in 8 files changed: 120 ins; 92 del; 328 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Fri Jan 13 04:04:37 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 13 Jan 2023 04:04:37 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 19:12:27 GMT, Archie L. Cobbs wrote: >> Uhm. Turns out I probably did not understand the filter correctly, and now I'm more dubious about what it actually does. Say you have this hierarchy: >> >> >> interface A { } >> class B { >> B() { >> A a = (A)this; >> ... >> } >> } >> class C extends B implements A { } >> ``` >> >> Pathological case, I know. But the filtering will end up dropping the expression Ref on the floor, right? (because B and A are unrelated). > >> But the filtering will end up dropping the expression Ref on the floor, right? (because B and A are unrelated). > > Ah, I see what you mean. > > Here's a more complete example: > > public class CastLeak { > > public CastLeak() { > ((CastLeak)(Runnable)this).mightLeak(); > } > > public void mightLeak() { > } > } > > That would be a leak for any subclass that implements `Runnable`. Yet no warning is generated. > > So the filtering by expression type is going to potentially create false negatives. But it also eliminates a bunch of false positives. And the false negatives are probably all somewhat pathological like the example above. > > So I still think it's worth doing. Ok - I thought false negative was the thing to absolutely avoid - and that was the no. 1 concern. I think a possible approach to keep both the filtering and the code more or less similar to what you have, is to save the type of the expression in the ExprRef. Then, I believe that, at the end of scan() you can just get whatever type is there, and check that it's the correct one, if not drop it. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 04:04:37 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 04:04:37 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Thu, 12 Jan 2023 21:47:28 GMT, Maurizio Cimadamore wrote: > Ok - I thought false negative was the thing to absolutely avoid - and that was the no. 1 concern. You're right. I think at the time I reasoned that it would be unusual enough for the type of an expression to start as an instanceof X, then change to not being an instanceof X, and then change back, that it was worth it to go ahead and filter these out. But admittedly that was based on intuition, not science. > I think a possible approach to keep both the filtering and the code more or less similar to what you have, is to save the type of the expression in the ExprRef. Then, I believe that, at the end of scan() you can just get whatever type is there, and check that it's the correct one, if not drop it. That's a nice idea... thanks. I'll play around with it some. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From rschmelter at openjdk.org Fri Jan 13 08:22:06 2023 From: rschmelter at openjdk.org (Ralf Schmelter) Date: Fri, 13 Jan 2023 08:22:06 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets Message-ID: This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. ------------- Commit messages: - Fixed trailing whitespace - Add IP address informationj to exception when socket connection failed Changes: https://git.openjdk.org/jdk/pull/11961/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=11961&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8299827 Stats: 15 lines in 2 files changed: 13 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/11961.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11961/head:pull/11961 PR: https://git.openjdk.org/jdk/pull/11961 From alanb at openjdk.org Fri Jan 13 08:44:16 2023 From: alanb at openjdk.org (Alan Bateman) Date: Fri, 13 Jan 2023 08:44:16 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets In-Reply-To: References: Message-ID: On Thu, 12 Jan 2023 08:21:35 GMT, Ralf Schmelter wrote: > This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. Enhanced exception message have to disabled by default but if they are enabled in some deployment then the proposal to include the IP address in the message should be okay. ------------- PR: https://git.openjdk.org/jdk/pull/11961 From alanb at openjdk.org Fri Jan 13 09:01:15 2023 From: alanb at openjdk.org (Alan Bateman) Date: Fri, 13 Jan 2023 09:01:15 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets In-Reply-To: References: Message-ID: On Thu, 12 Jan 2023 08:21:35 GMT, Ralf Schmelter wrote: > This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. src/java.base/share/classes/sun/net/util/SocketExceptions.java line 83: > 81: sb.append('('); > 82: sb.append(resolvedAddr); > 83: sb.append(')'); An alternative here might be to just use addr.toString() as it already handles both the resolved and unresolved cases and uses the most usual convention of hostname/ipaddress. ------------- PR: https://git.openjdk.org/jdk/pull/11961 From mcimadamore at openjdk.org Fri Jan 13 11:01:24 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 13 Jan 2023 11:01:24 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Thu, 12 Jan 2023 21:04:09 GMT, Archie L. Cobbs wrote: >> but what if `m` is a static method in a separate compilation unit? Should it be able to observe a partially initialized Foo? > > Caring about the proper initialization of any class in the _current_ compilation unit is an explicit non-goal. > > We only care about bugs where a superclass and subclass are in separate compilation units. So, to clarify, in this case: import java.util.*; class B { final Object ref; private B(Object ref) { Foo.consume(this); this.ref = ref; } } Even though `this` leaks to a method clearly before it is fully initialized, we do not care because there can be no subclass involved observing this. I guess I was confused because, while subclasses are a particularly sneaky case where uninitialized values can show up, the above leak seems potentially dangerous as well - we're effectively leaking a class whose final field has not been initialized! That said, if that was discussed, and it was decided for the warning not to deal with this case, that's ok. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Fri Jan 13 11:11:31 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 13 Jan 2023 11:11:31 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Fri, 13 Jan 2023 10:58:33 GMT, Maurizio Cimadamore wrote: >> Caring about the proper initialization of any class in the _current_ compilation unit is an explicit non-goal. >> >> We only care about bugs where a superclass and subclass are in separate compilation units. > > So, to clarify, in this case: > > > import java.util.*; > > class B { > final Object ref; > > private B(Object ref) { > Foo.consume(this); > this.ref = ref; > } > } > > > Even though `this` leaks to a method clearly before it is fully initialized, we do not care because there can be no subclass involved observing this. I guess I was confused because, while subclasses are a particularly sneaky case where uninitialized values can show up, the above leak seems potentially dangerous as well - we're effectively leaking a class whose final field has not been initialized! > > That said, if that was discussed, and it was decided for the warning not to deal with this case, that's ok. Perhaps my confusion might come from the name `this-escape` of the lint warning - which seems overpromising in this respect. But I looked at the description of the lint warning using `javac --help-lint` and I got this: this-escape Warn when a constructor invokes a method that could be overriden in a subclass; Which indeed aligns well with what this PR is doing. So that's ok. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Fri Jan 13 11:11:31 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 13 Jan 2023 11:11:31 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Fri, 13 Jan 2023 11:05:51 GMT, Maurizio Cimadamore wrote: >> So, to clarify, in this case: >> >> >> import java.util.*; >> >> class B { >> final Object ref; >> >> private B(Object ref) { >> Foo.consume(this); >> this.ref = ref; >> } >> } >> >> >> Even though `this` leaks to a method clearly before it is fully initialized, we do not care because there can be no subclass involved observing this. I guess I was confused because, while subclasses are a particularly sneaky case where uninitialized values can show up, the above leak seems potentially dangerous as well - we're effectively leaking a class whose final field has not been initialized! >> >> That said, if that was discussed, and it was decided for the warning not to deal with this case, that's ok. > > Perhaps my confusion might come from the name `this-escape` of the lint warning - which seems overpromising in this respect. But I looked at the description of the lint warning using `javac --help-lint` and I got this: > > > this-escape Warn when a constructor invokes a method that could be overriden in a subclass; > > > Which indeed aligns well with what this PR is doing. So that's ok. Something seems to be up with the lint description for this-escape - compare this: serial Warn about Serializable classes that do not have a serialVersionUID field. Also warn about other suspect declarations in Serializable and Externalizable classes and interfaces. with this: this-escape Warn when a constructor invokes a method that could be overriden in a subclass; such a method would execute before the subclass constructor completes its initialization. Indentation seems to be missing, which causes readability issues in the `--help-lint` output. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 13 12:45:34 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 12:45:34 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 04:04:36 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with 16 additional commits since the last revision: > > - Fix bug where all but the last yeild statement were being ignored. > - Add method RefSet.mapInto() and use to refactor/clean up. > - Fix possible assertion failure when handling if statements. > - Use Symbol methods isSubClass() and isEnclosedBy() instead of homebrew stuff. > > Suggested-by: mcimadamore > - Add comment regarding limitations of expresison type filtering. > - Add a few more DISABLED_WARNINGS to unbreak build. > - Clean up handling of switch expressions a bit. > - Remove unused method variant of analyzeTree(). > - Avoid all caps in comments. > - Clarify confusing comment. > - ... and 6 more: https://git.openjdk.org/jdk/compare/6e96a7d7...edf3c3f5 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 516: > 514: Name name = TreeInfo.name(invoke.meth); > 515: if (name == names._super) { > 516: scanInitializers(); it seems like the code scan initializers every time it finds a super() invocation, I guess that this scanning could be done once per class ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 13 14:34:40 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 14:34:40 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 04:04:36 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with 16 additional commits since the last revision: > > - Fix bug where all but the last yeild statement were being ignored. > - Add method RefSet.mapInto() and use to refactor/clean up. > - Fix possible assertion failure when handling if statements. > - Use Symbol methods isSubClass() and isEnclosedBy() instead of homebrew stuff. > > Suggested-by: mcimadamore > - Add comment regarding limitations of expresison type filtering. > - Add a few more DISABLED_WARNINGS to unbreak build. > - Clean up handling of switch expressions a bit. > - Remove unused method variant of analyzeTree(). > - Avoid all caps in comments. > - Clarify confusing comment. > - ... and 6 more: https://git.openjdk.org/jdk/compare/6e96a7d7...edf3c3f5 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 533: > 531: if (sym != null && > 532: sym.owner.kind == TYP && > 533: ((ClassSymbol)sym.owner).fullname == names.java_lang_Object && nit: in general we use another idiom for this in the compiler: sym.owner.type.tsym == syms.objectType.tsym where `syms` is an instance of: `com.sun.tools.javac.code.Symtab` ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 15:11:48 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 15:11:48 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Fri, 13 Jan 2023 11:08:33 GMT, Maurizio Cimadamore wrote: >> Perhaps my confusion might come from the name `this-escape` of the lint warning - which seems overpromising in this respect. But I looked at the description of the lint warning using `javac --help-lint` and I got this: >> >> >> this-escape Warn when a constructor invokes a method that could be overriden in a subclass; >> >> >> Which indeed aligns well with what this PR is doing. So that's ok. > > Something seems to be up with the lint description for this-escape - compare this: > > > serial Warn about Serializable classes that do not have a serialVersionUID field. > Also warn about other suspect declarations in Serializable and Externalizable classes and interfaces. > > with this: > > > this-escape Warn when a constructor invokes a method that could be overriden in a subclass; > such a method would execute before the subclass constructor completes its initialization. > > > Indentation seems to be missing, which causes readability issues in the `--help-lint` output. > I guess I was confused because, while subclasses are a particularly sneaky case where uninitialized values can show up, the above leak seems potentially dangerous as well... Yes - and this very question did come up in the discussions around this warning (see amber-dev). The decision was to go with drawing the "warning boundary" at the compilation unit. The reasoning is that (a) this aligns with the compiler's "knowledge boundary", i.e., we can know for sure from code inspection, and also (b) focuses the warning on the particularly pernicious aspect of these bugs, which is that they arise from the non-obvious interaction among two or more files - even when looking at any single one of those files, there doesn't seem to be any apparent problem. In other words, we decided "not to try to save any single source code from itself". But I think it's still an interesting question. Maybe experience will provide more guidance over time. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 15:11:49 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 15:11:49 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Fri, 13 Jan 2023 15:08:43 GMT, Archie L. Cobbs wrote: >> Something seems to be up with the lint description for this-escape - compare this: >> >> >> serial Warn about Serializable classes that do not have a serialVersionUID field. >> Also warn about other suspect declarations in Serializable and Externalizable classes and interfaces. >> >> with this: >> >> >> this-escape Warn when a constructor invokes a method that could be overriden in a subclass; >> such a method would execute before the subclass constructor completes its initialization. >> >> >> Indentation seems to be missing, which causes readability issues in the `--help-lint` output. > >> I guess I was confused because, while subclasses are a particularly sneaky case where uninitialized values can show up, the above leak seems potentially dangerous as well... > > Yes - and this very question did come up in the discussions around this warning (see amber-dev). > > The decision was to go with drawing the "warning boundary" at the compilation unit. The reasoning is that (a) this aligns with the compiler's "knowledge boundary", i.e., we can know for sure from code inspection, and also (b) focuses the warning on the particularly pernicious aspect of these bugs, which is that they arise from the non-obvious interaction among two or more files - even when looking at any single one of those files, there doesn't seem to be any apparent problem. In other words, we decided "not to try to save any single source code from itself". > > But I think it's still an interesting question. Maybe experience will provide more guidance over time. > Something seems to be up with the lint description for this-escape - compare this: Oops, will fix - thanks. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 15:16:59 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 15:16:59 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 12:42:24 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request incrementally with 16 additional commits since the last revision: >> >> - Fix bug where all but the last yeild statement were being ignored. >> - Add method RefSet.mapInto() and use to refactor/clean up. >> - Fix possible assertion failure when handling if statements. >> - Use Symbol methods isSubClass() and isEnclosedBy() instead of homebrew stuff. >> >> Suggested-by: mcimadamore >> - Add comment regarding limitations of expresison type filtering. >> - Add a few more DISABLED_WARNINGS to unbreak build. >> - Clean up handling of switch expressions a bit. >> - Remove unused method variant of analyzeTree(). >> - Avoid all caps in comments. >> - Clarify confusing comment. >> - ... and 6 more: https://git.openjdk.org/jdk/compare/6e96a7d7...edf3c3f5 > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 516: > >> 514: Name name = TreeInfo.name(invoke.meth); >> 515: if (name == names._super) { >> 516: scanInitializers(); > > it seems like the code scan initializers every time it finds a super() invocation, I guess that this scanning could be done once per class Yes... I did it that way is so that it doesn't require any adaptation if/when JDK-8194743 ever gets implemented. And it keeps the code a little simpler in exchange for a little redundancy. I'm happy to fix this if you think it is necessary though. > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 533: > >> 531: if (sym != null && >> 532: sym.owner.kind == TYP && >> 533: ((ClassSymbol)sym.owner).fullname == names.java_lang_Object && > > nit: in general we use another idiom for this in the compiler: > > sym.owner.type.tsym == syms.objectType.tsym > > where `syms` is an instance of: `com.sun.tools.javac.code.Symtab` Thanks - will fix. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Fri Jan 13 16:09:37 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Fri, 13 Jan 2023 16:09:37 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Fri, 13 Jan 2023 15:08:59 GMT, Archie L. Cobbs wrote: >>> I guess I was confused because, while subclasses are a particularly sneaky case where uninitialized values can show up, the above leak seems potentially dangerous as well... >> >> Yes - and this very question did come up in the discussions around this warning (see amber-dev). >> >> The decision was to go with drawing the "warning boundary" at the compilation unit. The reasoning is that (a) this aligns with the compiler's "knowledge boundary", i.e., we can know for sure from code inspection, and also (b) focuses the warning on the particularly pernicious aspect of these bugs, which is that they arise from the non-obvious interaction among two or more files - even when looking at any single one of those files, there doesn't seem to be any apparent problem. In other words, we decided "not to try to save any single source code from itself". >> >> But I think it's still an interesting question. Maybe experience will provide more guidance over time. > >> Something seems to be up with the lint description for this-escape - compare this: > > Oops, will fix - thanks. > The decision was to go with drawing the "warning boundary" at the compilation unit. The reasoning is that (a) this aligns with the compiler's "knowledge boundary", i.e., we can know for sure from code inspection, and also (b) focuses the warning on the particularly pernicious aspect of these bugs, which is that they arise from the non-obvious interaction among two or more files Sorry for being picky - you mention this "compilation unit" boundary before, but this is not really the reason here. Note that in my example B constructor calls out to a static method that is "outside" the boundary. The reason as to why my example is not flagged is simply that "escaping" is defined as "escaping into a subclass method", not just "escaping from the constructor (into some other compilation unit)". ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 13 16:15:32 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 16:15:32 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: <77lMG_P3_ZGjTegQictMdNN1IKjWixuzLWy5-GbHYnI=.bdbfc529-2ac8-4bba-b3a6-d08f0977e372@github.com> On Fri, 13 Jan 2023 15:14:05 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 516: >> >>> 514: Name name = TreeInfo.name(invoke.meth); >>> 515: if (name == names._super) { >>> 516: scanInitializers(); >> >> it seems like the code scan initializers every time it finds a super() invocation, I guess that this scanning could be done once per class > > Yes... I did it that way is so that it doesn't require any adaptation if/when JDK-8194743 ever gets implemented. And it keeps the code a little simpler in exchange for a little redundancy. > > I'm happy to fix this if you think it is necessary though. I'm OK either way we can revisit this later either as part of this PR or in a future one. I let it to your consideration ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 16:23:39 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 16:23:39 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> <2yMCKO6JFLW6MlAxdn1cRivontgIkZO8fCy-BexB6cg=.beb90f18-40b5-41eb-83c9-ec179e2ae2ff@github.com> Message-ID: On Fri, 13 Jan 2023 16:06:04 GMT, Maurizio Cimadamore wrote: >>> Something seems to be up with the lint description for this-escape - compare this: >> >> Oops, will fix - thanks. > >> The decision was to go with drawing the "warning boundary" at the compilation unit. The reasoning is that (a) this aligns with the compiler's "knowledge boundary", i.e., we can know for sure from code inspection, and also (b) focuses the warning on the particularly pernicious aspect of these bugs, which is that they arise from the non-obvious interaction among two or more files > > Sorry for being picky - you mention this "compilation unit" boundary before, but this is not really the reason here. Note that in my example B constructor calls out to a static method that is "outside" the boundary. The reason as to why my example is not flagged is simply that "escaping" is defined as "escaping into a subclass method", not just "escaping from the constructor (into some other compilation unit)". Oops, you're right, I answered the wrong question so to speak. The "must involve a subclass" requirement is another dimension on which a "boundary" was declared. This was also part of the original discussion. So yes the requirement is: "requires involvement of a subclass" **AND** "that subclass lives in a separate compilation unit". ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 16:23:42 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 16:23:42 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: <77lMG_P3_ZGjTegQictMdNN1IKjWixuzLWy5-GbHYnI=.bdbfc529-2ac8-4bba-b3a6-d08f0977e372@github.com> References: <77lMG_P3_ZGjTegQictMdNN1IKjWixuzLWy5-GbHYnI=.bdbfc529-2ac8-4bba-b3a6-d08f0977e372@github.com> Message-ID: On Fri, 13 Jan 2023 16:12:50 GMT, Vicente Romero wrote: >> Yes... I did it that way is so that it doesn't require any adaptation if/when JDK-8194743 ever gets implemented. And it keeps the code a little simpler in exchange for a little redundancy. >> >> I'm happy to fix this if you think it is necessary though. > > I'm OK either way we can revisit this later either as part of this PR or in a future one. I let it to your consideration Sounds good - thanks. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 13 17:38:27 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 17:38:27 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 04:04:36 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with 16 additional commits since the last revision: > > - Fix bug where all but the last yeild statement were being ignored. > - Add method RefSet.mapInto() and use to refactor/clean up. > - Fix possible assertion failure when handling if statements. > - Use Symbol methods isSubClass() and isEnclosedBy() instead of homebrew stuff. > > Suggested-by: mcimadamore > - Add comment regarding limitations of expresison type filtering. > - Add a few more DISABLED_WARNINGS to unbreak build. > - Clean up handling of switch expressions a bit. > - Remove unused method variant of analyzeTree(). > - Avoid all caps in comments. > - Clarify confusing comment. > - ... and 6 more: https://git.openjdk.org/jdk/compare/6e96a7d7...edf3c3f5 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 685: > 683: > 684: @Override > 685: public void visitDoLoop(JCDoWhileLoop tree) { I was thinking, code can also loop using labels and `break` / `continue`, not something we need to cover as part of this prototype but could be a future TODO that we can document ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 17:52:31 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 17:52:31 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 17:35:08 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request incrementally with 16 additional commits since the last revision: >> >> - Fix bug where all but the last yeild statement were being ignored. >> - Add method RefSet.mapInto() and use to refactor/clean up. >> - Fix possible assertion failure when handling if statements. >> - Use Symbol methods isSubClass() and isEnclosedBy() instead of homebrew stuff. >> >> Suggested-by: mcimadamore >> - Add comment regarding limitations of expresison type filtering. >> - Add a few more DISABLED_WARNINGS to unbreak build. >> - Clean up handling of switch expressions a bit. >> - Remove unused method variant of analyzeTree(). >> - Avoid all caps in comments. >> - Clarify confusing comment. >> - ... and 6 more: https://git.openjdk.org/jdk/compare/6e96a7d7...edf3c3f5 > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 685: > >> 683: >> 684: @Override >> 685: public void visitDoLoop(JCDoWhileLoop tree) { > > I was thinking, code can also loop using labels and `break` / `continue`, not something we need to cover as part of this prototype but could be a future TODO that we can document Hah - I didn't think of that. But actually I don't think we would miss anything (see if you agree). The code "executes" every loop, in a sort-of simulation, adding references until the set of references converges. Moreover, that reference set is "append only" while this is happening. Therefore, during actual execution, a break or continue may cause less code to be executed than in our simulation, but never more code than our simulation. So during actual execution it might be that fewer actual 'this' references are created, but never more. Therefore, this effect might cause false positives (which of course we already have with loops and code in general because we take all possible branches), but never false negatives. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From rschmelter at openjdk.org Fri Jan 13 18:21:46 2023 From: rschmelter at openjdk.org (Ralf Schmelter) Date: Fri, 13 Jan 2023 18:21:46 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v2] In-Reply-To: References: Message-ID: > This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: Simplified code ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11961/files - new: https://git.openjdk.org/jdk/pull/11961/files/e862b212..bfec2899 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11961&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11961&range=00-01 Stats: 16 lines in 2 files changed: 0 ins; 13 del; 3 mod Patch: https://git.openjdk.org/jdk/pull/11961.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11961/head:pull/11961 PR: https://git.openjdk.org/jdk/pull/11961 From rschmelter at openjdk.org Fri Jan 13 18:27:30 2023 From: rschmelter at openjdk.org (Ralf Schmelter) Date: Fri, 13 Jan 2023 18:27:30 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v2] In-Reply-To: References: Message-ID: <8P9oaKssSxZHJFC0Mh0qI6ZTvNCWjXIxl5EFpXcWIYw=.5882bd1d-766b-4730-bb8e-7c962c558f21@github.com> On Fri, 13 Jan 2023 08:58:53 GMT, Alan Bateman wrote: >> Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: >> >> Simplified code > > src/java.base/share/classes/sun/net/util/SocketExceptions.java line 83: > >> 81: sb.append('('); >> 82: sb.append(resolvedAddr); >> 83: sb.append(')'); > > An alternative here might be to just use addr.toString() as it already handles both the resolved and unresolved cases and uses the most usual convention of hostname/ipaddress. That's a good idea. It even removes code instead of adding more. I've update the PR accordingly. ------------- PR: https://git.openjdk.org/jdk/pull/11961 From duke at openjdk.org Fri Jan 13 19:09:54 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 19:09:54 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: - Use more idiomatic test for java.lang.Object. - Revert 27cb30129; the error was actually fixed in edf3c3f51. - Fix formatting issue with the "this-escape" --help-lint description. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/edf3c3f5..ae37ff7c Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=08 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=07-08 Stats: 12 lines in 3 files changed: 3 ins; 4 del; 5 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 13 19:20:29 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 19:20:29 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: Message-ID: <9xqxePs8UvBJIyPMojy6Bjbl7h3VguJcIwjFhbPr_78=.5ed61dac-21e7-4214-8faf-85f5612f5b46@github.com> On Fri, 13 Jan 2023 17:49:05 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 685: >> >>> 683: >>> 684: @Override >>> 685: public void visitDoLoop(JCDoWhileLoop tree) { >> >> I was thinking, code can also loop using labels and `break` / `continue`, not something we need to cover as part of this prototype but could be a future TODO that we can document > > Hah - I didn't think of that. But actually I don't think we would miss anything (see if you agree). > > The code "executes" every loop, in a sort-of simulation, adding references until the set of references converges. Moreover, that reference set is "append only" while this is happening. > > Therefore, during actual execution, a break or continue may cause less code to be executed than in our simulation, but never more code than our simulation. So during actual execution it might be that fewer actual 'this' references are created, but never more. > > Therefore, this effect might cause false positives (which of course we already have with loops and code in general because we take all possible branches), but never false negatives. yep I agree ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 13 20:19:53 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 20:19:53 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 19:09:54 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Use more idiomatic test for java.lang.Object. > - Revert 27cb30129; the error was actually fixed in edf3c3f51. > - Fix formatting issue with the "this-escape" --help-lint description. test/langtools/tools/javac/warnings/ThisEscape/ThisEscapeBasic.java line 8: > 6: */ > 7: > 8: public class ThisEscapeBasic { I wonder if it could be better to just fold most of these tests in particular the small ones and create just one, or a few tests, with several subclasses, that will reduce the overhead if in the future we change the code and we need to change the golden files. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vromero at openjdk.org Fri Jan 13 20:24:46 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 20:24:46 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 19:09:54 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: > > - Use more idiomatic test for java.lang.Object. > - Revert 27cb30129; the error was actually fixed in edf3c3f51. > - Fix formatting issue with the "this-escape" --help-lint description. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1088: > 1086: private void visitLooped(T tree, Consumer visitor) { > 1087: visitScoped(tree, false, t -> { > 1088: while (true) { I have also been thinking if the loop analysis could go wild and execute a large, unbound number of times. But it seems from Archie's experiments that this probably won't occur in "normal" code and worst case scenario if that were to occur we can always limit the number of times we will process loops to a set number of times ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 21:23:24 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 21:23:24 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 20:16:25 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: >> >> - Use more idiomatic test for java.lang.Object. >> - Revert 27cb30129; the error was actually fixed in edf3c3f51. >> - Fix formatting issue with the "this-escape" --help-lint description. > > test/langtools/tools/javac/warnings/ThisEscape/ThisEscapeBasic.java line 8: > >> 6: */ >> 7: >> 8: public class ThisEscapeBasic { > > I wonder if it could be better to just fold most of these tests in particular the small ones and create just one, or a few tests, with several subclasses, that will reduce the overhead if in the future we change the code and we need to change the golden files. I really don't have any informed opinion on this. I can see arguments both ways... putting all you eggs in one basket can be seen alternately as foolhardy or highly efficient :) FWIW in the past I've had problems with trying to combine multiples tests that generate errors into one file. The compiler seems to like to bail out early when it sees errors. I guess that experience was working subconsciously. Of course that doesn't apply here as these are all warnings. And a bunch of separate files make the test run slower. So I agree with you - I'll consolidate them. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 21:31:25 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 21:31:25 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 20:21:24 GMT, Vicente Romero wrote: >> Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: >> >> - Use more idiomatic test for java.lang.Object. >> - Revert 27cb30129; the error was actually fixed in edf3c3f51. >> - Fix formatting issue with the "this-escape" --help-lint description. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1088: > >> 1086: private void visitLooped(T tree, Consumer visitor) { >> 1087: visitScoped(tree, false, t -> { >> 1088: while (true) { > > I have also been thinking if the loop analysis could go wild and execute a large, unbound number of times. But it seems from Archie's experiments that this probably won't occur in "normal" code and worst case scenario if that were to occur we can always limit the number of times we will process loops to a set number of times The number of times around any single loop is bounded by the number of new references that can possibly be created during the analysis of that loop. That number is at most 2 * (1 + 1 + 1 + 1 + N) where N is the number of parameters and/or variables declared in that scope (the 2 is for direct or indirect, and the 1's are for each of the singleton reference types `ThisRef`, `OuterRef`, `ExprRef`, and `ReturnRef`). If you have nested scopes A, B, C each with Na, Nb, and Nc variables declared therein (respectively), then the bound would be something like 2 * (1 + 1 + 1 + 1 + Na + (Na * Nb) + (Na * Nb * Nc)) worst case (waving hands here). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Fri Jan 13 21:36:30 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 21:36:30 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: <77lMG_P3_ZGjTegQictMdNN1IKjWixuzLWy5-GbHYnI=.bdbfc529-2ac8-4bba-b3a6-d08f0977e372@github.com> Message-ID: On Fri, 13 Jan 2023 16:20:41 GMT, Archie L. Cobbs wrote: >> I'm OK either way we can revisit this later either as part of this PR or in a future one. I let it to your consideration > > Sounds good - thanks. Ah. I just realized that we need to do it your way because of the following bug: Suppose you have a constructor and a field with initializer that both leak, but you have `@SuppressWarnings("this-escape")` on the constructor. Then the leak for the field will never be reported because we never get to it. I'll fix. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From darcy at openjdk.org Fri Jan 13 21:52:55 2023 From: darcy at openjdk.org (Joe Darcy) Date: Fri, 13 Jan 2023 21:52:55 GMT Subject: RFR: JDK-8300133: Use generalized see and link tags in core libs Message-ID: With generalized see and link tags that can refer to anchors (JDK-8200337), the see and link tags in core libraries should be updated to use this feature when possible. This PR covers such updates for java.base. ------------- Commit messages: - JDK-8300133: Use generalized see and link tags in core libs Changes: https://git.openjdk.org/jdk/pull/12000/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12000&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8300133 Stats: 107 lines in 10 files changed: 0 ins; 19 del; 88 mod Patch: https://git.openjdk.org/jdk/pull/12000.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12000/head:pull/12000 PR: https://git.openjdk.org/jdk/pull/12000 From vromero at openjdk.org Fri Jan 13 22:04:03 2023 From: vromero at openjdk.org (Vicente Romero) Date: Fri, 13 Jan 2023 22:04:03 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v8] In-Reply-To: References: <77lMG_P3_ZGjTegQictMdNN1IKjWixuzLWy5-GbHYnI=.bdbfc529-2ac8-4bba-b3a6-d08f0977e372@github.com> Message-ID: <1ylDnjbWJwdsJP-dVL1zthfhVHZbcOgnC3gxgNuKBZk=.6367e3b4-18ae-4232-b43a-c469e58f9a2d@github.com> On Fri, 13 Jan 2023 21:33:02 GMT, Archie L. Cobbs wrote: >> Sounds good - thanks. > > Ah. I just realized that we need to do it your way because of the following bug: > > Suppose you have a constructor and a field with initializer that both leak, but you have `@SuppressWarnings("this-escape")` on the constructor. > > Then the leak for the field will never be reported because we never get to it. > > I'll fix. yep, right in that case that leak wouldn't be reported ------------- PR: https://git.openjdk.org/jdk/pull/11874 From jlu at openjdk.org Fri Jan 13 22:15:55 2023 From: jlu at openjdk.org (Justin Lu) Date: Fri, 13 Jan 2023 22:15:55 GMT Subject: [jdk20] RFR: 8299499: Usage of constructors of primitive wrapper classes should be avoided in java.net API docs Message-ID: This pull request contains a backport of commit [63cf4aa0](https://github.com/openjdk/jdk/commit/63cf4aa0c897406fc9370a8e05cb035caafc5d69) from the [openjdk/jdk](https://git.openjdk.org/jdk) repository. The commit being backported was authored by Justin Lu on 7 Jan 2023 and was reviewed by Naoto Sato and Jaikiran Pai. Thanks! ------------- Commit messages: - Backport 63cf4aa0c897406fc9370a8e05cb035caafc5d69 Changes: https://git.openjdk.org/jdk20/pull/108/files Webrev: https://webrevs.openjdk.org/?repo=jdk20&pr=108&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8299499 Stats: 3 lines in 1 file changed: 0 ins; 0 del; 3 mod Patch: https://git.openjdk.org/jdk20/pull/108.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/108/head:pull/108 PR: https://git.openjdk.org/jdk20/pull/108 From jjg at openjdk.org Fri Jan 13 22:33:13 2023 From: jjg at openjdk.org (Jonathan Gibbons) Date: Fri, 13 Jan 2023 22:33:13 GMT Subject: RFR: JDK-8300133: Use generalized see and link tags in core libs In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 21:30:06 GMT, Joe Darcy wrote: > With generalized see and link tags that can refer to anchors (JDK-8200337), the see and link tags in core libraries should be updated to use this feature when possible. This PR covers such updates for java.base. Nice to see all those ` References: Message-ID: On Fri, 13 Jan 2023 21:30:06 GMT, Joe Darcy wrote: > With generalized see and link tags that can refer to anchors (JDK-8200337), the see and link tags in core libraries should be updated to use this feature when possible. This PR covers such updates for java.base. src/java.base/share/classes/java/util/ResourceBundle.java line 270: > 268: * are packaged in a JAR file. Resource bundle only JAR file can be readily > 269: * deployed as an {@linkplain java.lang.module.ModuleFinder##automatic-modules > 270: * automatic module1}. For example, if the JAR file contains the Typo: extra `1` ------------- PR: https://git.openjdk.org/jdk/pull/12000 From mchung at openjdk.org Fri Jan 13 22:46:10 2023 From: mchung at openjdk.org (Mandy Chung) Date: Fri, 13 Jan 2023 22:46:10 GMT Subject: RFR: JDK-8300133: Use generalized see and link tags in core libs In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 21:30:06 GMT, Joe Darcy wrote: > With generalized see and link tags that can refer to anchors (JDK-8200337), the see and link tags in core libraries should be updated to use this feature when possible. This PR covers such updates for java.base. src/java.base/share/classes/java/util/ResourceBundle.java line 270: > 268: * are packaged in a JAR file. Resource bundle only JAR file can be readily > 269: * deployed as an {@linkplain java.lang.module.ModuleFinder##automatic-modules > 270: * automatic module1}. For example, if the JAR file contains the typo : `module1`? ------------- PR: https://git.openjdk.org/jdk/pull/12000 From duke at openjdk.org Fri Jan 13 22:48:59 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Fri, 13 Jan 2023 22:48:59 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v10] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: - Fix bug where field initializer warnings could be incorrectly suppressed. - Consolidate all the unit tests that generate warnings into one. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/ae37ff7c..0b06dc32 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=09 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=08-09 Stats: 1454 lines in 35 files changed: 658 ins; 762 del; 34 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From darcy at openjdk.org Fri Jan 13 22:54:47 2023 From: darcy at openjdk.org (Joe Darcy) Date: Fri, 13 Jan 2023 22:54:47 GMT Subject: RFR: JDK-8300133: Use generalized see and link tags in core libs [v2] In-Reply-To: References: Message-ID: > With generalized see and link tags that can refer to anchors (JDK-8200337), the see and link tags in core libraries should be updated to use this feature when possible. This PR covers such updates for java.base. Joe Darcy has updated the pull request incrementally with one additional commit since the last revision: Fix typo found in code review. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12000/files - new: https://git.openjdk.org/jdk/pull/12000/files/aa623f2a..0e4d4e4b Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12000&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12000&range=00-01 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/12000.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12000/head:pull/12000 PR: https://git.openjdk.org/jdk/pull/12000 From mchung at openjdk.org Fri Jan 13 22:54:47 2023 From: mchung at openjdk.org (Mandy Chung) Date: Fri, 13 Jan 2023 22:54:47 GMT Subject: RFR: JDK-8300133: Use generalized see and link tags in core libs [v2] In-Reply-To: References: Message-ID: <1y-NxkBIqDQ4RlBuXC7czlGB-jsPd3m8jNrPD9-wzUk=.9eb0f9d7-a9cc-4791-88c8-b3253ea97607@github.com> On Fri, 13 Jan 2023 22:50:53 GMT, Joe Darcy wrote: >> With generalized see and link tags that can refer to anchors (JDK-8200337), the see and link tags in core libraries should be updated to use this feature when possible. This PR covers such updates for java.base. > > Joe Darcy has updated the pull request incrementally with one additional commit since the last revision: > > Fix typo found in code review. Marked as reviewed by mchung (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12000 From naoto at openjdk.org Fri Jan 13 22:54:47 2023 From: naoto at openjdk.org (Naoto Sato) Date: Fri, 13 Jan 2023 22:54:47 GMT Subject: RFR: JDK-8300133: Use generalized see and link tags in core libs [v2] In-Reply-To: References: Message-ID: <0TIQXjqLz5hGjV--Pr4KjUIloBfbXIRlXf5j9EK4TnA=.970794a6-fc1e-4b6b-a82a-9e886abd0111@github.com> On Fri, 13 Jan 2023 22:50:53 GMT, Joe Darcy wrote: >> With generalized see and link tags that can refer to anchors (JDK-8200337), the see and link tags in core libraries should be updated to use this feature when possible. This PR covers such updates for java.base. > > Joe Darcy has updated the pull request incrementally with one additional commit since the last revision: > > Fix typo found in code review. Changes in `ResoruceBundle` look good. ------------- Marked as reviewed by naoto (Reviewer). PR: https://git.openjdk.org/jdk/pull/12000 From darcy at openjdk.org Fri Jan 13 22:54:48 2023 From: darcy at openjdk.org (Joe Darcy) Date: Fri, 13 Jan 2023 22:54:48 GMT Subject: RFR: JDK-8300133: Use generalized see and link tags in core libs [v2] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 22:38:32 GMT, Naoto Sato wrote: >> Joe Darcy has updated the pull request incrementally with one additional commit since the last revision: >> >> Fix typo found in code review. > > src/java.base/share/classes/java/util/ResourceBundle.java line 270: > >> 268: * are packaged in a JAR file. Resource bundle only JAR file can be readily >> 269: * deployed as an {@linkplain java.lang.module.ModuleFinder##automatic-modules >> 270: * automatic module1}. For example, if the JAR file contains the > > Typo: extra `1` Doh! Thanks; fixed in next push. ------------- PR: https://git.openjdk.org/jdk/pull/12000 From jlu at openjdk.org Fri Jan 13 23:21:11 2023 From: jlu at openjdk.org (Justin Lu) Date: Fri, 13 Jan 2023 23:21:11 GMT Subject: [jdk20] Integrated: 8299499: Usage of constructors of primitive wrapper classes should be avoided in java.net API docs In-Reply-To: References: Message-ID: <90TNoknKYsr4Ppy1CMtwPa6Mhih6RoKhdxvBoOt7Uvg=.29ddf6c7-4456-46e8-8eff-e0acfb23253d@github.com> On Fri, 13 Jan 2023 22:08:20 GMT, Justin Lu wrote: > This pull request contains a backport of commit [63cf4aa0](https://github.com/openjdk/jdk/commit/63cf4aa0c897406fc9370a8e05cb035caafc5d69) from the [openjdk/jdk](https://git.openjdk.org/jdk) repository. > > The commit being backported was authored by Justin Lu on 7 Jan 2023 and was reviewed by Naoto Sato and Jaikiran Pai. > > Thanks! This pull request has now been integrated. Changeset: dc5cc616 Author: Justin Lu Committer: Naoto Sato URL: https://git.openjdk.org/jdk20/commit/dc5cc61621ec6ad23e6107737b46276171d90622 Stats: 3 lines in 1 file changed: 0 ins; 0 del; 3 mod 8299499: Usage of constructors of primitive wrapper classes should be avoided in java.net API docs Backport-of: 63cf4aa0c897406fc9370a8e05cb035caafc5d69 ------------- PR: https://git.openjdk.org/jdk20/pull/108 From duke at openjdk.org Sat Jan 14 01:57:32 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Sat, 14 Jan 2023 01:57:32 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v7] In-Reply-To: References: <7lxiY8WIdkIkI5fqLn52qkq2fvSc04huqWL_fV2WSy8=.7bd29e16-bcee-473e-937e-aea32b211db3@github.com> Message-ID: On Fri, 13 Jan 2023 00:57:14 GMT, Archie L. Cobbs wrote: >> Ok - I thought false negative was the thing to absolutely avoid - and that was the no. 1 concern. I think a possible approach to keep both the filtering and the code more or less similar to what you have, is to save the type of the expression in the ExprRef. Then, I believe that, at the end of scan() you can just get whatever type is there, and check that it's the correct one, if not drop it. > >> Ok - I thought false negative was the thing to absolutely avoid - and that was the no. 1 concern. > > You're right. I think at the time I reasoned that it would be unusual enough for the type of an expression to start as an instanceof X, then change to not being an instanceof X, and then change back, that it was worth it to go ahead and filter these out. But admittedly that was based on intuition, not science. > >> I think a possible approach to keep both the filtering and the code more or less similar to what you have, is to save the type of the expression in the ExprRef. Then, I believe that, at the end of scan() you can just get whatever type is there, and check that it's the correct one, if not drop it. > > That's a nice idea... thanks. I'll play around with it some. I was curious how much of a difference this type filtering makes, so I built the JDK with and without it. The results were identical except for one case: package java.lang.invoke; ... public abstract sealed class CallSite permits ConstantCallSite, MutableCallSite, VolatileCallSite { ... CallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable { this(targetType); // need to initialize target to make CallSite.type() work in createTargetHook ConstantCallSite selfCCS = (ConstantCallSite) this; MethodHandle boundTarget = (MethodHandle) createTargetHook.invokeWithArguments(selfCCS); setTargetNormal(boundTarget); // ConstantCallSite doesn't publish CallSite.target UNSAFE.storeStoreFence(); // barrier between target and isFrozen updates } When we do type filtering, `(ConstantCallSite) this` causes the 'this' reference to be discarded so no leak is reported on the next line for `invokeWithArguments(selfCCS)`. Just a side note, there is also a leak on the next line because final method `setTargetNormal()` invokes `MethodHandleNatives.setCallSiteTargetNormal(this, newTarget)`, so a leak does get reported anyway even with type filtering. When type filtering is disabled, we report a leak at `invokeWithArguments(selfCCS)` - which is accurate. So what did we learn? First it looks like type filtering has very minimal effect. I think this is because it requires some version of two casts in a row in and out of type compatibility, and this is probably very rare. But looking at the one data point we do have, the type filtering did in fact cause a false negative. And when building the entire JDK, it causes zero net new false positives. So to me this is evidence that we should just remove the type filtering altogether... @vicente-romero-oracle your thoughts? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From vtewari at openjdk.org Sat Jan 14 05:15:10 2023 From: vtewari at openjdk.org (Vyom Tewari) Date: Sat, 14 Jan 2023 05:15:10 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v2] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 18:21:46 GMT, Ralf Schmelter wrote: >> This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. > > Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: > > Simplified code src/java.base/share/classes/sun/net/util/SocketExceptions.java line 75: > 73: sb.append(": "); > 74: sb.append(addr.toString()); > 75: String enhancedMsg = sb.toString(); do you need extra "enhancedMsg" ? you can directly use "return create(e, sb.toString());" ------------- PR: https://git.openjdk.org/jdk/pull/11961 From alanb at openjdk.org Sat Jan 14 08:13:10 2023 From: alanb at openjdk.org (Alan Bateman) Date: Sat, 14 Jan 2023 08:13:10 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v2] In-Reply-To: References: Message-ID: On Sat, 14 Jan 2023 05:12:08 GMT, Vyom Tewari wrote: >> Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: >> >> Simplified code > > src/java.base/share/classes/sun/net/util/SocketExceptions.java line 75: > >> 73: sb.append(": "); >> 74: sb.append(addr.toString()); >> 75: String enhancedMsg = sb.toString(); > > do you need extra "enhancedMsg" ? you can directly use "return create(e, sb.toString());" Yes, and can reduced further with String.join return create(e, String.join(": ", e.getMessage(), addr.toString())); ------------- PR: https://git.openjdk.org/jdk/pull/11961 From rschmelter at openjdk.org Mon Jan 16 09:34:33 2023 From: rschmelter at openjdk.org (Ralf Schmelter) Date: Mon, 16 Jan 2023 09:34:33 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v3] In-Reply-To: References: Message-ID: > This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: Further simplification ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11961/files - new: https://git.openjdk.org/jdk/pull/11961/files/bfec2899..7e136b79 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11961&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11961&range=01-02 Stats: 7 lines in 1 file changed: 0 ins; 6 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/11961.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11961/head:pull/11961 PR: https://git.openjdk.org/jdk/pull/11961 From rschmelter at openjdk.org Mon Jan 16 09:34:34 2023 From: rschmelter at openjdk.org (Ralf Schmelter) Date: Mon, 16 Jan 2023 09:34:34 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v2] In-Reply-To: References: Message-ID: On Sat, 14 Jan 2023 08:10:25 GMT, Alan Bateman wrote: >> src/java.base/share/classes/sun/net/util/SocketExceptions.java line 75: >> >>> 73: sb.append(": "); >>> 74: sb.append(addr.toString()); >>> 75: String enhancedMsg = sb.toString(); >> >> do you need extra "enhancedMsg" ? you can directly use "return create(e, sb.toString());" > > Yes, and can reduced further with String.join > > return create(e, String.join(": ", e.getMessage(), addr.toString())); Cool, that's really short. I've updated the PR. ------------- PR: https://git.openjdk.org/jdk/pull/11961 From mcimadamore at openjdk.org Mon Jan 16 11:56:24 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 16 Jan 2023 11:56:24 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v10] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 22:48:59 GMT, Archie L. Cobbs wrote: >> This PR adds a new lint warning category `this-escape`. >> >> It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. >> >> A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ >> * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) >> * Some constructor `B()` of `B` invokes `A()` as its superclass constructor >> * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly >> >> In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. >> >> Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. >> >> From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. >> >> For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. >> >> More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. >> >> Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. >> >> Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. >> >> **Patch Navigation Guide** >> >> * Non-trivial compiler changes: >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` >> * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` >> >> * Javadoc additions of `@implNote`: >> >> * `src/java.base/share/classes/java/io/PipedReader.java` >> * `src/java.base/share/classes/java/io/PipedWriter.java` >> * `src/java.base/share/classes/java/lang/Throwable.java` >> * `src/java.base/share/classes/java/util/ArrayDeque.java` >> * `src/java.base/share/classes/java/util/EnumMap.java` >> * `src/java.base/share/classes/java/util/HashSet.java` >> * `src/java.base/share/classes/java/util/Hashtable.java` >> * `src/java.base/share/classes/java/util/LinkedList.java` >> * `src/java.base/share/classes/java/util/TreeMap.java` >> * `src/java.base/share/classes/java/util/TreeSet.java` >> >> * New unit tests >> * `test/langtools/tools/javac/warnings/ThisEscape/*.java` >> >> * **Everything else** is just adding `@SuppressWarnings("this-escape")` > > Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: > > - Fix bug where field initializer warnings could be incorrectly suppressed. > - Consolidate all the unit tests that generate warnings into one. src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1096: > 1094: > 1095: // Perform the given action within a new scope > 1096: private void visitScoped(boolean promote, Runnable action) { type-variable unused here? ------------- PR: https://git.openjdk.org/jdk/pull/11874 From alanb at openjdk.org Mon Jan 16 12:03:23 2023 From: alanb at openjdk.org (Alan Bateman) Date: Mon, 16 Jan 2023 12:03:23 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v3] In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 09:34:33 GMT, Ralf Schmelter wrote: >> This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. > > Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: > > Further simplification src/java.base/share/classes/sun/net/util/SocketExceptions.java line 30: > 28: import java.io.IOException; > 29: import java.lang.reflect.Constructor; > 30: import java.net.InetAddress; I assume this import doesn't need to be added now. src/java.base/share/classes/sun/net/util/SocketExceptions.java line 80: > 78: > 79: private static IOException ofUnixDomain(IOException e, UnixDomainSocketAddress addr) { > 80: return create(e, String.join(": ", e.getMessage(), addr.toString())); This is ofUnixDomain, did you mean to change this one? InetSocketAddress::toString specifies the string representation, UnixDomainSocketAddress does not. ------------- PR: https://git.openjdk.org/jdk/pull/11961 From mcimadamore at openjdk.org Mon Jan 16 12:54:22 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 16 Jan 2023 12:54:22 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 21:28:51 GMT, Archie L. Cobbs wrote: >> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1088: >> >>> 1086: private void visitLooped(T tree, Consumer visitor) { >>> 1087: visitScoped(tree, false, t -> { >>> 1088: while (true) { >> >> I have also been thinking if the loop analysis could go wild and execute a large, unbound number of times. But it seems from Archie's experiments that this probably won't occur in "normal" code and worst case scenario if that were to occur we can always limit the number of times we will process loops to a set number of times > > The number of times around any single loop is bounded by the number of new references that can possibly be created during the analysis of that loop. > > That number is at most 2 * (1 + 1 + 1 + 1 + N) where N is the number of parameters and/or variables declared in that scope (the 2 is for direct or indirect, and the 1's are for each of the singleton reference types `ThisRef`, `OuterRef`, `ExprRef`, and `ReturnRef`). > > If you have nested scopes A, B, C each with Na, Nb, and Nc variables declared therein (respectively), then the bound would be something like 2 * (1 + 1 + 1 + 1 + Na + (Na * Nb) + (Na * Nb * Nc)) worst case (waving hands here). I have played a bit with the patch, trying to disable certain features. The main reason to deal with loops and recursive calls the way the patch does is to eliminate false positives. If we see a loop, and we can't perform the analysis multiple times (as the PR does), then we'd have to conclude that the loop can be potentially escaping (as we might have missed an local var update). Same goes for recursive calls (e.g. a recursive call would be treated as escaping). Same goes for analyzing invoked methods that fall in the same compilation unit. If we don't do that, more methods might look as "escaping". So, here's what I found: * compiling the JDK with the current patch produces 2376 warnings * disabling support for recursive calls produces 2427 warnings * treating all method calls inside a loop to be escaping produces 2464 warnings * disabling scanning of methods in same compilation unit produces 4317 warnings (Note: the patches I used to do this analysis are a bit blunt, and perhaps can be made a bit less conservative, which might result in less false positives added - I just went for the simplest possible approach, just to test the contribute of each analysis). This seems to suggest that even a blunt approach to deal with recursion and loop does not result in a significant increase of false positives (~2% more). That said, disabling scanning of methods in the same compilation unit results in a big impact in terms of false positive (~100% increase). So, I'm pretty confident that, should performance problems arise, we could probably dial back the analysis not to do loops (or to do them in a bounded way, as Vicente suggest, which is much better of what I tried here) - and that will probably give us the same results we have today (or a very very minor increase of false positives). But scanning of dependent methods in same compilation unit seems to be more or less a must-have. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From dfuchs at openjdk.org Mon Jan 16 15:14:11 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Mon, 16 Jan 2023 15:14:11 GMT Subject: RFR: JDK-8300133: Use generalized see and link tags in core libs [v2] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 22:54:47 GMT, Joe Darcy wrote: >> With generalized see and link tags that can refer to anchors (JDK-8200337), the see and link tags in core libraries should be updated to use this feature when possible. This PR covers such updates for java.base. > > Joe Darcy has updated the pull request incrementally with one additional commit since the last revision: > > Fix typo found in code review. src/java.base/share/classes/java/lang/CharSequence.java line 76: > 74: * > 75: *

If the {@code char} value specified by the index is a > 76: * {@linkplain Character##unicode surrogate}, the surrogate value I didn't know about the `##` trick. Is that a new feature to target an HTML anchor? ------------- PR: https://git.openjdk.org/jdk/pull/12000 From duke at openjdk.org Mon Jan 16 15:49:28 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 16 Jan 2023 15:49:28 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v10] In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 11:53:40 GMT, Maurizio Cimadamore wrote: >> Archie L. Cobbs has updated the pull request incrementally with two additional commits since the last revision: >> >> - Fix bug where field initializer warnings could be incorrectly suppressed. >> - Consolidate all the unit tests that generate warnings into one. > > src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java line 1096: > >> 1094: >> 1095: // Perform the given action within a new scope >> 1096: private void visitScoped(boolean promote, Runnable action) { > > type-variable unused here? Thanks - will fix. ------------- PR: https://git.openjdk.org/jdk/pull/11874 From duke at openjdk.org Mon Jan 16 16:32:25 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 16 Jan 2023 16:32:25 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: References: Message-ID: <-vggQR3X6BuroIsmEmI6yohrVGF3MyE-ap7tokjc-7M=.077053ee-fcf9-43db-be53-a9c89ab38a15@github.com> On Mon, 16 Jan 2023 12:51:49 GMT, Maurizio Cimadamore wrote: >> The number of times around any single loop is bounded by the number of new references that can possibly be created during the analysis of that loop. >> >> That number is at most 2 * (1 + 1 + 1 + 1 + N) where N is the number of parameters and/or variables declared in that scope (the 2 is for direct or indirect, and the 1's are for each of the singleton reference types `ThisRef`, `OuterRef`, `ExprRef`, and `ReturnRef`). >> >> If you have nested scopes A, B, C each with Na, Nb, and Nc variables declared therein (respectively), then the bound would be something like 2 * (1 + 1 + 1 + 1 + Na + (Na * Nb) + (Na * Nb * Nc)) worst case (waving hands here). > > I have played a bit with the patch, trying to disable certain features. The main reason to deal with loops and recursive calls the way the patch does is to eliminate false positives. If we see a loop, and we can't perform the analysis multiple times (as the PR does), then we'd have to conclude that the loop can be potentially escaping (as we might have missed an local var update). Same goes for recursive calls (e.g. a recursive call would be treated as escaping). Same goes for analyzing invoked methods that fall in the same compilation unit. If we don't do that, more methods might look as "escaping". > > So, here's what I found: > > * compiling the JDK with the current patch produces 2376 warnings > * disabling support for recursive calls produces 2427 warnings > * treating all method calls inside a loop to be escaping produces 2464 warnings > * disabling scanning of methods in same compilation unit produces 4317 warnings > > (Note: the patches I used to do this analysis are a bit blunt, and perhaps can be made a bit less conservative, which might result in less false positives added - I just went for the simplest possible approach, just to test the contribute of each analysis). > > This seems to suggest that even a blunt approach to deal with recursion and loop does not result in a significant increase of false positives (~2% more). That said, disabling scanning of methods in the same compilation unit results in a big impact in terms of false positive (~100% increase). > > So, I'm pretty confident that, should performance problems arise, we could probably dial back the analysis not to do loops (or to do them in a bounded way, as Vicente suggest, which is much better of what I tried here) - and that will probably give us the same results we have today (or a very very minor increase of false positives). But scanning of dependent methods in same compilation unit seems to be more or less a must-have. Thanks for doing that analysis - very interesting. It looks like you might be counting the "here via invocation" lines as separate warnings. These are really part of the previous `possible 'this' escape` line, e.g.: .../java/awt/Frame.java:429: Note: possible 'this' escape before subclass is fully initialized init(title, null); ^ .../java/awt/Frame.java:460: Note: previous possible 'this' escape happens here via invocation SunToolkit.checkAndSetPolicy(this); ^ Semi-related... I was also curious what would happen if we changed the semantics of the warning from "subclass must be in a separate compilation unit" to "subclass must be in a separate package". I'm not proposing we change this definition, and obviously there are trade-offs in where you draw this boundary, but was curious anywan (at one point I thought it might be worth having an option for this, e.g., with variants like `-Xlint:this-escape` vs. `-Xlint:this-escape:package`, or even `-Xlint:this-escape:module`, etc.). In any case, here are the results: * Warnings for subclass in separate compilation unit: 2093 * Warnings for subclass in separate package: 1334 So a 36% reduction - not too surprising since the JDK includes a bunch of non-public implementation classes. FWIW this is the patch I used: diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java index e81df22b017..f309a4742aa 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java @@ -216,24 +217,24 @@ class ThisEscapeAnalyzer extends TreeScanner { private Lint lint = ThisEscapeAnalyzer.this.lint; private JCClassDecl currentClass; - private boolean privateOuter; + private boolean nonPublicOuter; @Override public void visitClassDef(JCClassDecl tree) { JCClassDecl currentClassPrev = currentClass; - boolean privateOuterPrev = privateOuter; + boolean nonPublicOuterPrev = nonPublicOuter; Lint lintPrev = lint; lint = lint.augment(tree.sym); try { currentClass = tree; - privateOuter |= tree.sym.isAnonymous(); - privateOuter |= (tree.mods.flags & Flags.PRIVATE) != 0; + nonPublicOuter |= tree.sym.isAnonymous(); + nonPublicOuter |= (tree.mods.flags & Flags.PUBLIC) == 0; // Recurse super.visitClassDef(tree); } finally { currentClass = currentClassPrev; - privateOuter = privateOuterPrev; + nonPublicOuter = nonPublicOuterPrev; lint = lintPrev; } } @@ -268,10 +269,10 @@ class ThisEscapeAnalyzer extends TreeScanner { // Determine if this is a constructor we should analyze boolean analyzable = currentClassIsExternallyExtendable() && TreeInfo.isConstructor(tree) && - !tree.sym.isPrivate() && + (tree.sym.isPublic() || (tree.sym.flags() & Flags.PROTECTED) != 0) && !suppressed.contains(tree.sym); - // Determine if this method is "invokable" in an analysis (can't be overridden) + // Determine if this method is "invokable" in an analysis (can't be overridden outside package) boolean invokable = !currentClassIsExternallyExtendable() || TreeInfo.isConstructor(tree) || (tree.mods.flags & (Flags.STATIC | Flags.PRIVATE | Flags.FINAL)) != 0; @@ -286,12 +287,13 @@ class ThisEscapeAnalyzer extends TreeScanner { } } - // Determines if the current class could be extended in some external compilation unit + // Determines if the current class could be extended in some other package private boolean currentClassIsExternallyExtendable() { return !currentClass.sym.isFinal() && + currentClass.sym.isPublic() && !(currentClass.sym.isSealed() && currentClass.permitting.isEmpty()) && !(currentClass.sym.owner.kind == MTH) && - !privateOuter; + !nonPublicOuter; } }.scan(env.tree); ------------- PR: https://git.openjdk.org/jdk/pull/11874 From mcimadamore at openjdk.org Mon Jan 16 17:16:26 2023 From: mcimadamore at openjdk.org (Maurizio Cimadamore) Date: Mon, 16 Jan 2023 17:16:26 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v9] In-Reply-To: <-vggQR3X6BuroIsmEmI6yohrVGF3MyE-ap7tokjc-7M=.077053ee-fcf9-43db-be53-a9c89ab38a15@github.com> References: <-vggQR3X6BuroIsmEmI6yohrVGF3MyE-ap7tokjc-7M=.077053ee-fcf9-43db-be53-a9c89ab38a15@github.com> Message-ID: On Mon, 16 Jan 2023 16:29:31 GMT, Archie L. Cobbs wrote: > It looks like you might be counting the "here via invocation" lines as separate warnings. These are really part of the previous `possible 'this' escape` line, e.g.: yes, I really did the simplest possible thing (e.g. just counting the number of escape-this warnings, regardless of their kinds). Perhaps some of my measurements might be skewed as a result - but I think that magnitude-wise they are still telling. > > ``` > .../java/awt/Frame.java:429: Note: possible 'this' escape before subclass is fully initialized > init(title, null); > ^ > .../java/awt/Frame.java:460: Note: previous possible 'this' escape happens here via invocation > SunToolkit.checkAndSetPolicy(this); > ^ > ``` > > Semi-related... I was also curious what would happen if we changed the semantics of the warning from "subclass must be in a separate compilation unit" to "subclass must be in a separate package". To be fair, this is what my brain was reading when you talked about "compilation unit" - but then saw that the code was doing it differently. You see, for "sealed" classes we have a notion of "maintenance domain". E.g. the classes in a `permits` clause of a `sealed` declaration must belong to the same module (if available) or same package (if no module is available). That's how you get the exhaustiveness analysis and all the goodies, by essentially making a close-world assumption on the classes that are passed to javac for a given compilation task. I think it would make a lot of sense to apply these very same boundaries to the escape-this analysis (and, in fact, when looking at warnings coming out of the JDK, I often found false positives that were caused by this). > > I'm not proposing we change this definition, and obviously there are trade-offs in where you draw this boundary, but was curious anywan (at one point I thought it might be worth having an option for this, e.g., with variants like `-Xlint:this-escape` vs. `-Xlint:this-escape:package`, or even `-Xlint:this-escape:module`, etc.). Perhaps - but, as said above, `sealed` already does this by default - so there's a (strong) precedent, I believe, should we want to bend the analysis that way. > > In any case, here are the results: > > * Warnings for subclass in separate compilation unit: 2093 > > * Warnings for subclass in separate package: 1334 > > > So a 36% reduction - not too surprising since the JDK includes a bunch of non-public implementation classes. That corresponds to what I've sampled (unscientifically). ------------- PR: https://git.openjdk.org/jdk/pull/11874 From dfuchs at openjdk.org Mon Jan 16 17:33:10 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Mon, 16 Jan 2023 17:33:10 GMT Subject: RFR: JDK-8300133: Use generalized see and link tags in core libs [v2] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 22:54:47 GMT, Joe Darcy wrote: >> With generalized see and link tags that can refer to anchors (JDK-8200337), the see and link tags in core libraries should be updated to use this feature when possible. This PR covers such updates for java.base. > > Joe Darcy has updated the pull request incrementally with one additional commit since the last revision: > > Fix typo found in code review. Changes to InetAddressResolverProvider.java look good. ------------- PR: https://git.openjdk.org/jdk/pull/12000 From rriggs at openjdk.org Mon Jan 16 17:33:12 2023 From: rriggs at openjdk.org (Roger Riggs) Date: Mon, 16 Jan 2023 17:33:12 GMT Subject: RFR: JDK-8300133: Use generalized see and link tags in core libs [v2] In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 15:06:25 GMT, Daniel Fuchs wrote: >> Joe Darcy has updated the pull request incrementally with one additional commit since the last revision: >> >> Fix typo found in code review. > > src/java.base/share/classes/java/lang/CharSequence.java line 76: > >> 74: * >> 75: *

If the {@code char} value specified by the index is a >> 76: * {@linkplain Character##unicode surrogate}, the surrogate value > > I didn't know about the `##` trick. Is that a new feature to target an HTML anchor? The CSR has a concise description: [JDK-8294195](https://bugs.openjdk.org/browse/JDK-8294195) Generalize see and link tags for user-defined anchors ------------- PR: https://git.openjdk.org/jdk/pull/12000 From dfuchs at openjdk.org Mon Jan 16 18:15:52 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Mon, 16 Jan 2023 18:15:52 GMT Subject: RFR: 8300172: java/net/httpclient/MappingResponseSubscriber.java failed with java.net.ConnectException Message-ID: The MappingResponseSubscriber test has been observed failing on windows in our CI due to a ConnectException. I am suspecting that some kind of connection limit enforced by the system has been reached. We can see from the log that the TCP connection has failed, been retried, and failed again. Previous connections to the same server seem to have succeeded. Modifying the test to wait after previous clients have been GC'ed before opening the next one could alleviate the situation. ------------- Commit messages: - 8300172 Changes: https://git.openjdk.org/jdk/pull/12013/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12013&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8300172 Stats: 28 lines in 1 file changed: 20 ins; 0 del; 8 mod Patch: https://git.openjdk.org/jdk/pull/12013.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12013/head:pull/12013 PR: https://git.openjdk.org/jdk/pull/12013 From duke at openjdk.org Mon Jan 16 23:22:00 2023 From: duke at openjdk.org (Archie L. Cobbs) Date: Mon, 16 Jan 2023 23:22:00 GMT Subject: RFR: 8015831: Add lint check for calling overridable methods from a constructor [v11] In-Reply-To: References: Message-ID: > This PR adds a new lint warning category `this-escape`. > > It also adds `@SuppressWarnings` annotations as needed to the JDK itself to allow the JDK to continue to compile with `-Xlint:all`. > > A 'this' escape warning is generated for a constructor `A()` in a class `A` when the compiler detects that the following situation is _in theory possible:_ > * Some subclass `B extends A` exists, and `B` is defined in a separate source file (i.e., compilation unit) > * Some constructor `B()` of `B` invokes `A()` as its superclass constructor > * During the execution of `A()`, some non-static method of `B.foo()` could get invoked, perhaps indirectly > > In the above scenario, `B.foo()` would execute before `A()` has returned and before `B()` has performed any initialization. To the extent `B.foo()` accesses any fields of `B` - all of which are still uninitialized - it is likely to function incorrectly. > > Note, when determining if a 'this' escape is possible, the compiler makes no assumptions about code outside of the current compilation unit. It doesn't look outside of the current source file to see what might actually happen when a method is invoked. It does follow method and constructors within the current compilation unit, and applies a simplified union-of-all-possible-branches data flow analysis to see where 'this' could end up. > > From my review, virtually all of the warnings generated in the various JDK modules are valid warnings in the sense that a 'this' escape, as defined above, is really and truly possible. However, that doesn't imply that any bugs were found within the JDK - only that the possibility of a certain type of bug exists if certain superclass constructors are used by someone, somewhere, someday. > > For several "popular" classes, this PR also adds `@implNote`'s to the offending constructors so that subclass implementors are made aware of the threat. For one example, `TreeMap(Map)` invokes `putAll()` and `put()`. > > More details and a couple of motivating examples are given in an included [doc file](https://github.com/archiecobbs/jdk/blob/ThisEscape/src/java.base/share/classes/java/lang/doc-files/ThisEscape.html) that these `@implNote`'s link to. See also the recent thread on `amber-dev` for some background. > > Ideally, over time the owners of the various modules would review their `@SuppressWarnings("this-escape")` annotations and determine which other constructors also warranted such an `@implNote`. > > Because of all the`@SuppressWarnings` annotations, this PR touches a bunch of different JDK modules. My apologies for that. Adding these annotations was determined to be the more conservative approach, as compared to just excepting `this-escape` from various module builds globally. > > **Patch Navigation Guide** > > * Non-trivial compiler changes: > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ThisEscapeAnalyzer.java` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties` > * `src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties` > > * Javadoc additions of `@implNote`: > > * `src/java.base/share/classes/java/io/PipedReader.java` > * `src/java.base/share/classes/java/io/PipedWriter.java` > * `src/java.base/share/classes/java/lang/Throwable.java` > * `src/java.base/share/classes/java/util/ArrayDeque.java` > * `src/java.base/share/classes/java/util/EnumMap.java` > * `src/java.base/share/classes/java/util/HashSet.java` > * `src/java.base/share/classes/java/util/Hashtable.java` > * `src/java.base/share/classes/java/util/LinkedList.java` > * `src/java.base/share/classes/java/util/TreeMap.java` > * `src/java.base/share/classes/java/util/TreeSet.java` > > * New unit tests > * `test/langtools/tools/javac/warnings/ThisEscape/*.java` > > * **Everything else** is just adding `@SuppressWarnings("this-escape")` Archie L. Cobbs has updated the pull request incrementally with three additional commits since the last revision: - Remove unused type variable on method visitScoped(). - Remove expression type filtering; it doesn't seem to be needed. - Clean up unused import. ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11874/files - new: https://git.openjdk.org/jdk/pull/11874/files/0b06dc32..a0b4310d Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=10 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11874&range=09-10 Stats: 21 lines in 2 files changed: 0 ins; 20 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/11874.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11874/head:pull/11874 PR: https://git.openjdk.org/jdk/pull/11874 From rschmelter at openjdk.org Tue Jan 17 09:22:36 2023 From: rschmelter at openjdk.org (Ralf Schmelter) Date: Tue, 17 Jan 2023 09:22:36 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v4] In-Reply-To: References: Message-ID: > This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: Accidentally changed Unix domain socket exception text instead of socket exception text ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11961/files - new: https://git.openjdk.org/jdk/pull/11961/files/7e136b79..074f212f Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11961&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11961&range=02-03 Stats: 11 lines in 1 file changed: 5 ins; 5 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/11961.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11961/head:pull/11961 PR: https://git.openjdk.org/jdk/pull/11961 From alanb at openjdk.org Tue Jan 17 09:28:13 2023 From: alanb at openjdk.org (Alan Bateman) Date: Tue, 17 Jan 2023 09:28:13 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v4] In-Reply-To: References: Message-ID: On Tue, 17 Jan 2023 09:22:36 GMT, Ralf Schmelter wrote: >> This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. > > Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: > > Accidentally changed Unix domain socket exception text instead of socket exception text Marked as reviewed by alanb (Reviewer). Latest version looks okay, I assume you'll update the end date in the copyright header before integrating. ------------- PR: https://git.openjdk.org/jdk/pull/11961 From vtewari at openjdk.org Tue Jan 17 12:29:16 2023 From: vtewari at openjdk.org (Vyom Tewari) Date: Tue, 17 Jan 2023 12:29:16 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v4] In-Reply-To: References: Message-ID: On Tue, 17 Jan 2023 09:22:36 GMT, Ralf Schmelter wrote: >> This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. > > Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: > > Accidentally changed Unix domain socket exception text instead of socket exception text Looks OK to me. ------------- Marked as reviewed by vtewari (Committer). PR: https://git.openjdk.org/jdk/pull/11961 From ccleary at openjdk.org Tue Jan 17 15:29:16 2023 From: ccleary at openjdk.org (Conor Cleary) Date: Tue, 17 Jan 2023 15:29:16 GMT Subject: RFR: 8296410: HttpClient throws java.io.IOException: no statuscode in response for HTTP2 Message-ID: ### **Description** With HTTP/2, a possible flow of an exchange could be that a Server responds to a simple request by sending response headers within a HEADERS frame, the requested resources and trailing headers with another HEADERS frame including the END_HEADERS and END_STREAM flags (if they were not previously given in the Response Headers). Usually an HTTP/2 client should opt-in to make use of trailing headers though this behaviour is not supoorted by default with the HttpClient. It is still possible in any case that a trailing HEADERS frame can be sent, even if the frame just carries flags and no headers specified in the header block. This edge case was causing an IOException to be thrown and the client to shut down unexpectedly. ### **Summary of Changes & Justification** In Stream, a means to track the state of whether or not a final status code for an exchange has been received was added to prevent the exception occuring due to a HEADERS frame with no status code arriving after response headers were received. In the case of a partial response (status codes in the 1XX range), the flag for receiving a final response code is not set until a response outside of the 1XX range is received. Lastly, if trailing headers are received, they are logged and dumped. The response headers consumer is then reset. --------- ### Progress - [ ] Change must be properly reviewed (1 review required, with at least 1 [Reviewer](https://openjdk.org/bylaws#reviewer)) - [x] Change must not contain extraneous whitespace - [x] Commit message must refer to an issue ### Reviewing

Using git Checkout this PR locally: \ `$ git fetch https://git.openjdk.org/jdk pull/12028/head:pull/12028` \ `$ git checkout pull/12028` Update a local copy of the PR: \ `$ git checkout pull/12028` \ `$ git pull https://git.openjdk.org/jdk pull/12028/head`
Using Skara CLI tools Checkout this PR locally: \ `$ git pr checkout 12028` View PR using the GUI difftool: \ `$ git pr show -t 12028`
Using diff file Download this PR as a diff file: \ https://git.openjdk.org/jdk/pull/12028.diff
------------- Commit messages: - 8296410: Updated copyright header - 8296410: Use empty trailers instead of sample ones - 8296410: HttpClient throws java.io.IOException: no statuscode in response for HTTP2 Changes: https://git.openjdk.org/jdk/pull/12028/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12028&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8296410 Stats: 252 lines in 2 files changed: 236 ins; 4 del; 12 mod Patch: https://git.openjdk.org/jdk/pull/12028.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12028/head:pull/12028 PR: https://git.openjdk.org/jdk/pull/12028 From jpai at openjdk.org Wed Jan 18 06:49:20 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 18 Jan 2023 06:49:20 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v2] In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 09:30:17 GMT, Ralf Schmelter wrote: >> Yes, and can reduced further with String.join >> >> return create(e, String.join(": ", e.getMessage(), addr.toString())); > > Cool, that's really short. I've updated the PR. Hello @schmelter-sap, The javadoc of `String.join` states that it can throw a `NullPointerException` if any of the elements in `null`. As far as I can see, the `IOException` that may get thrown, probably isn't guaranteed to have a exception message, in which case this will run into a `NullPointerException`. Perhaps we should guard this code against that possibility? ------------- PR: https://git.openjdk.org/jdk/pull/11961 From jpai at openjdk.org Wed Jan 18 06:53:20 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 18 Jan 2023 06:53:20 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v4] In-Reply-To: References: Message-ID: On Tue, 17 Jan 2023 09:22:36 GMT, Ralf Schmelter wrote: >> This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. > > Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: > > Accidentally changed Unix domain socket exception text instead of socket exception text test/jdk/java/net/Socket/ExceptionText.java line 114: > 112: return; // has no detail msg > 113: System.err.println("msg = " + msg); > 114: throw new RuntimeException("Test failed: exception does not contain address info: " + msg); It might help debugging any unexpected failures, if the exception message here could include the expected address. Something like: throw new RuntimeException("Test failed: exception message " + msg + " does not contain address " + dest); ------------- PR: https://git.openjdk.org/jdk/pull/11961 From jpai at openjdk.org Wed Jan 18 07:16:21 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 18 Jan 2023 07:16:21 GMT Subject: RFR: 8300172: java/net/httpclient/MappingResponseSubscriber.java failed with java.net.ConnectException In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 18:08:29 GMT, Daniel Fuchs wrote: > The MappingResponseSubscriber test has been observed failing on windows in our CI due to a ConnectException. > I am suspecting that some kind of connection limit enforced by the system has been reached. > We can see from the log that the TCP connection has failed, been retried, and failed again. > Previous connections to the same server seem to have succeeded. > > Modifying the test to wait after previous clients have been GC'ed before opening the next one could alleviate the situation. test/jdk/java/net/httpclient/MappingResponseSubscriber.java line 149: > 147: System.gc(); > 148: AssertionError error = TRACKER.check(tracker, 1500); > 149: if (error != null) throw error; Hello Daniel, in theory, this could potentially lose the any original failure/exception that the test in the try block might have raised. Perhaps we could catch and throw the original exception and add this additional failure as a suppressed exception to it? ------------- PR: https://git.openjdk.org/jdk/pull/12013 From alanb at openjdk.org Wed Jan 18 07:22:21 2023 From: alanb at openjdk.org (Alan Bateman) Date: Wed, 18 Jan 2023 07:22:21 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v2] In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 06:46:55 GMT, Jaikiran Pai wrote: >> Cool, that's really short. I've updated the PR. > > Hello @schmelter-sap, The javadoc of `String.join` states that it can throw a `NullPointerException` if any of the elements in `null`. As far as I can see, the `IOException` that may get thrown, probably isn't guaranteed to have a exception message, in which case this will run into a `NullPointerException`. Perhaps we should guard this code against that possibility? Right now, if "enhanced socket exceptions" is enabled, then it only be used for socket/network exceptions. These will have some exception messages but you are right that catering for this possibility would be good, to avoid needing to change it again in the future. ------------- PR: https://git.openjdk.org/jdk/pull/11961 From jpai at openjdk.org Wed Jan 18 07:28:25 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 18 Jan 2023 07:28:25 GMT Subject: RFR: 8296410: HttpClient throws java.io.IOException: no statuscode in response for HTTP2 In-Reply-To: References: Message-ID: On Tue, 17 Jan 2023 10:58:54 GMT, Conor Cleary wrote: > ### **Description** > With HTTP/2, a possible flow of an exchange could be that a Server responds to a simple request by sending response headers within a HEADERS frame, the requested resources and trailing headers with another HEADERS frame including the END_HEADERS and END_STREAM flags (if they were not previously given in the Response Headers). Usually an HTTP/2 client should opt-in to make use of trailing headers though this behaviour is not supoorted by default with the HttpClient. > > It is still possible in any case that a trailing HEADERS frame can be sent, even if the frame just carries flags and no headers specified in the header block. This edge case was causing an IOException to be thrown and the client to shut down unexpectedly. > > ### **Summary of Changes & Justification** > In Stream, a means to track the state of whether or not a final status code for an exchange has been received was added to prevent the exception occuring due to a HEADERS frame with no status code arriving after response headers were received. In the case of a partial response (status codes in the 1XX range), the flag for receiving a final response code is not set until a response outside of the 1XX range is received. > > Lastly, if trailing headers are received, they are logged and dumped. The response headers consumer is then reset. > > --------- > ### Progress > - [ ] Change must be properly reviewed (1 review required, with at least 1 [Reviewer](https://openjdk.org/bylaws#reviewer)) > - [x] Change must not contain extraneous whitespace > - [x] Commit message must refer to an issue > > > > ### Reviewing >
Using git > > Checkout this PR locally: \ > `$ git fetch https://git.openjdk.org/jdk pull/12028/head:pull/12028` \ > `$ git checkout pull/12028` > > Update a local copy of the PR: \ > `$ git checkout pull/12028` \ > `$ git pull https://git.openjdk.org/jdk pull/12028/head` > >
>
Using Skara CLI tools > > Checkout this PR locally: \ > `$ git pr checkout 12028` > > View PR using the GUI difftool: \ > `$ git pr show -t 12028` > >
>
Using diff file > > Download this PR as a diff file: \ > https://git.openjdk.org/jdk/pull/12028.diff > >
test/jdk/java/net/httpclient/http2/TrailingHeadersTest.java line 2: > 1: /* > 2: * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. Hello Conor, this appears to be a typo. Given that this is a new file, only 2023 would be relevant. ------------- PR: https://git.openjdk.org/jdk/pull/12028 From jpai at openjdk.org Wed Jan 18 09:22:30 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 18 Jan 2023 09:22:30 GMT Subject: RFR: 8296410: HttpClient throws java.io.IOException: no statuscode in response for HTTP2 In-Reply-To: References: Message-ID: On Tue, 17 Jan 2023 10:58:54 GMT, Conor Cleary wrote: > ### **Description** > With HTTP/2, a possible flow of an exchange could be that a Server responds to a simple request by sending response headers within a HEADERS frame, the requested resources and trailing headers with another HEADERS frame including the END_HEADERS and END_STREAM flags (if they were not previously given in the Response Headers). Usually an HTTP/2 client should opt-in to make use of trailing headers though this behaviour is not supoorted by default with the HttpClient. > > It is still possible in any case that a trailing HEADERS frame can be sent, even if the frame just carries flags and no headers specified in the header block. This edge case was causing an IOException to be thrown and the client to shut down unexpectedly. > > ### **Summary of Changes & Justification** > In Stream, a means to track the state of whether or not a final status code for an exchange has been received was added to prevent the exception occuring due to a HEADERS frame with no status code arriving after response headers were received. In the case of a partial response (status codes in the 1XX range), the flag for receiving a final response code is not set until a response outside of the 1XX range is received. > > Lastly, if trailing headers are received, they are logged and dumped. The response headers consumer is then reset. > > --------- > ### Progress > - [ ] Change must be properly reviewed (1 review required, with at least 1 [Reviewer](https://openjdk.org/bylaws#reviewer)) > - [x] Change must not contain extraneous whitespace > - [x] Commit message must refer to an issue > > > > ### Reviewing >
Using git > > Checkout this PR locally: \ > `$ git fetch https://git.openjdk.org/jdk pull/12028/head:pull/12028` \ > `$ git checkout pull/12028` > > Update a local copy of the PR: \ > `$ git checkout pull/12028` \ > `$ git pull https://git.openjdk.org/jdk pull/12028/head` > >
>
Using Skara CLI tools > > Checkout this PR locally: \ > `$ git pr checkout 12028` > > View PR using the GUI difftool: \ > `$ git pr show -t 12028` > >
>
Using diff file > > Download this PR as a diff file: \ > https://git.openjdk.org/jdk/pull/12028.diff > >
The changes in this PR look good to me. While looking at the source code, I noticed that the `Stream` class has a `PushedStream` nested class which too has a similar implementation in `handleResponse()`. I haven't yet checked the spec related to this; do you know if this code too will need a similar fix? ------------- PR: https://git.openjdk.org/jdk/pull/12028 From rschmelter at openjdk.org Wed Jan 18 09:42:37 2023 From: rschmelter at openjdk.org (Ralf Schmelter) Date: Wed, 18 Jan 2023 09:42:37 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v5] In-Reply-To: References: Message-ID: > This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: Improve exception message in test ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11961/files - new: https://git.openjdk.org/jdk/pull/11961/files/074f212f..3cf476df Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11961&range=04 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11961&range=03-04 Stats: 2 lines in 1 file changed: 0 ins; 1 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/11961.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11961/head:pull/11961 PR: https://git.openjdk.org/jdk/pull/11961 From rschmelter at openjdk.org Wed Jan 18 09:42:39 2023 From: rschmelter at openjdk.org (Ralf Schmelter) Date: Wed, 18 Jan 2023 09:42:39 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v4] In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 06:50:25 GMT, Jaikiran Pai wrote: >> Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: >> >> Accidentally changed Unix domain socket exception text instead of socket exception text > > test/jdk/java/net/Socket/ExceptionText.java line 114: > >> 112: return; // has no detail msg >> 113: System.err.println("msg = " + msg); >> 114: throw new RuntimeException("Test failed: exception does not contain address info: " + msg); > > It might help debugging any unexpected failures, if the exception message here could include the expected address. Something like: > > throw new RuntimeException("Test failed: exception message " + msg + " does not contain address " + dest); I've added the destination and removed the System.err.println() call above, since it now seems redundant. ------------- PR: https://git.openjdk.org/jdk/pull/11961 From dfuchs at openjdk.org Wed Jan 18 11:02:21 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Wed, 18 Jan 2023 11:02:21 GMT Subject: RFR: 8300172: java/net/httpclient/MappingResponseSubscriber.java failed with java.net.ConnectException In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 07:13:10 GMT, Jaikiran Pai wrote: >> The MappingResponseSubscriber test has been observed failing on windows in our CI due to a ConnectException. >> I am suspecting that some kind of connection limit enforced by the system has been reached. >> We can see from the log that the TCP connection has failed, been retried, and failed again. >> Previous connections to the same server seem to have succeeded. >> >> Modifying the test to wait after previous clients have been GC'ed before opening the next one could alleviate the situation. > > test/jdk/java/net/httpclient/MappingResponseSubscriber.java line 149: > >> 147: System.gc(); >> 148: AssertionError error = TRACKER.check(tracker, 1500); >> 149: if (error != null) throw error; > > Hello Daniel, in theory, this could potentially lose the any original failure/exception that the test in the try block might have raised. Perhaps we could catch and throw the original exception and add this additional failure as a suppressed exception to it? Good point! Let me fix that. ------------- PR: https://git.openjdk.org/jdk/pull/12013 From dfuchs at openjdk.org Wed Jan 18 11:11:39 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Wed, 18 Jan 2023 11:11:39 GMT Subject: RFR: 8300172: java/net/httpclient/MappingResponseSubscriber.java failed with java.net.ConnectException [v2] In-Reply-To: References: Message-ID: > The MappingResponseSubscriber test has been observed failing on windows in our CI due to a ConnectException. > I am suspecting that some kind of connection limit enforced by the system has been reached. > We can see from the log that the TCP connection has failed, been retried, and failed again. > Previous connections to the same server seem to have succeeded. > > Modifying the test to wait after previous clients have been GC'ed before opening the next one could alleviate the situation. Daniel Fuchs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains three additional commits since the last revision: - Merge branch 'master' into MappingResponseSubscriber-8300172 - Original exception might be lost with try-finally - 8300172 ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12013/files - new: https://git.openjdk.org/jdk/pull/12013/files/1433b632..097e25bd Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12013&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12013&range=00-01 Stats: 4431 lines in 587 files changed: 2414 ins; 519 del; 1498 mod Patch: https://git.openjdk.org/jdk/pull/12013.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12013/head:pull/12013 PR: https://git.openjdk.org/jdk/pull/12013 From jpai at openjdk.org Wed Jan 18 11:15:28 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 18 Jan 2023 11:15:28 GMT Subject: RFR: 8300172: java/net/httpclient/MappingResponseSubscriber.java failed with java.net.ConnectException [v2] In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 11:11:39 GMT, Daniel Fuchs wrote: >> The MappingResponseSubscriber test has been observed failing on windows in our CI due to a ConnectException. >> I am suspecting that some kind of connection limit enforced by the system has been reached. >> We can see from the log that the TCP connection has failed, been retried, and failed again. >> Previous connections to the same server seem to have succeeded. >> >> Modifying the test to wait after previous clients have been GC'ed before opening the next one could alleviate the situation. > > Daniel Fuchs has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains three additional commits since the last revision: > > - Merge branch 'master' into MappingResponseSubscriber-8300172 > - Original exception might be lost with try-finally > - 8300172 This now looks fine to me. Sorry, I previously thought I had added comment about copyright year needing an update, but looks like I didn't. Please update the copyright year before integrating. ------------- Marked as reviewed by jpai (Reviewer). PR: https://git.openjdk.org/jdk/pull/12013 From dfuchs at openjdk.org Wed Jan 18 11:37:36 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Wed, 18 Jan 2023 11:37:36 GMT Subject: RFR: 8300172: java/net/httpclient/MappingResponseSubscriber.java failed with java.net.ConnectException [v3] In-Reply-To: References: Message-ID: > The MappingResponseSubscriber test has been observed failing on windows in our CI due to a ConnectException. > I am suspecting that some kind of connection limit enforced by the system has been reached. > We can see from the log that the TCP connection has failed, been retried, and failed again. > Previous connections to the same server seem to have succeeded. > > Modifying the test to wait after previous clients have been GC'ed before opening the next one could alleviate the situation. Daniel Fuchs has updated the pull request incrementally with two additional commits since the last revision: - Update Copyright years - Update Copyright years ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12013/files - new: https://git.openjdk.org/jdk/pull/12013/files/097e25bd..d24c824a Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12013&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12013&range=01-02 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/12013.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12013/head:pull/12013 PR: https://git.openjdk.org/jdk/pull/12013 From dfuchs at openjdk.org Wed Jan 18 11:44:24 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Wed, 18 Jan 2023 11:44:24 GMT Subject: RFR: 8296410: HttpClient throws java.io.IOException: no statuscode in response for HTTP2 In-Reply-To: References: Message-ID: <7AIQEkQAJ8gNZR7Quz3-lTxlUkMNFdTSSlp3s9cT0Cs=.7be692db-87fc-49eb-834b-db86566ff2b1@github.com> On Wed, 18 Jan 2023 09:20:00 GMT, Jaikiran Pai wrote: > The changes in this PR look good to me. While looking at the source code, I noticed that the Stream class has a PushedStream nested class which too has a similar implementation in handleResponse(). I haven't yet checked the spec related to this; do you know if this code too will need a similar fix? Hmm... Probably. Good point! ------------- PR: https://git.openjdk.org/jdk/pull/12028 From ccleary at openjdk.org Wed Jan 18 11:50:18 2023 From: ccleary at openjdk.org (Conor Cleary) Date: Wed, 18 Jan 2023 11:50:18 GMT Subject: RFR: 8296410: HttpClient throws java.io.IOException: no statuscode in response for HTTP2 In-Reply-To: <7AIQEkQAJ8gNZR7Quz3-lTxlUkMNFdTSSlp3s9cT0Cs=.7be692db-87fc-49eb-834b-db86566ff2b1@github.com> References: <7AIQEkQAJ8gNZR7Quz3-lTxlUkMNFdTSSlp3s9cT0Cs=.7be692db-87fc-49eb-834b-db86566ff2b1@github.com> Message-ID: On Wed, 18 Jan 2023 11:41:46 GMT, Daniel Fuchs wrote: > The changes in this PR look good to me. While looking at the source code, I noticed that the `Stream` class has a `PushedStream` nested class which too has a similar implementation in `handleResponse()`. I haven't yet checked the spec related to this; do you know if this code too will need a similar fix? Good point Jaikirian, I'll conduct a small investigation into that and see whats required. Thank you for the keen eye as always! Updates to follow soon ------------- PR: https://git.openjdk.org/jdk/pull/12028 From rschmelter at openjdk.org Wed Jan 18 14:01:59 2023 From: rschmelter at openjdk.org (Ralf Schmelter) Date: Wed, 18 Jan 2023 14:01:59 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v6] In-Reply-To: References: Message-ID: > This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: Adjusted copyright headers ------------- Changes: - all: https://git.openjdk.org/jdk/pull/11961/files - new: https://git.openjdk.org/jdk/pull/11961/files/3cf476df..a69d844b Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=11961&range=05 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=11961&range=04-05 Stats: 2 lines in 2 files changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/11961.diff Fetch: git fetch https://git.openjdk.org/jdk pull/11961/head:pull/11961 PR: https://git.openjdk.org/jdk/pull/11961 From jpai at openjdk.org Wed Jan 18 14:27:27 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 18 Jan 2023 14:27:27 GMT Subject: RFR: 8300172: java/net/httpclient/MappingResponseSubscriber.java failed with java.net.ConnectException [v3] In-Reply-To: References: Message-ID: <3oLU1VHpb10DEpBVrsBFbIa9O4YwU2iPOyrP8LWxAi0=.a57587ed-3916-4738-b21e-2b9613ad27a2@github.com> On Wed, 18 Jan 2023 11:37:36 GMT, Daniel Fuchs wrote: >> The MappingResponseSubscriber test has been observed failing on windows in our CI due to a ConnectException. >> I am suspecting that some kind of connection limit enforced by the system has been reached. >> We can see from the log that the TCP connection has failed, been retried, and failed again. >> Previous connections to the same server seem to have succeeded. >> >> Modifying the test to wait after previous clients have been GC'ed before opening the next one could alleviate the situation. > > Daniel Fuchs has updated the pull request incrementally with two additional commits since the last revision: > > - Update Copyright years > - Update Copyright years Marked as reviewed by jpai (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12013 From dfuchs at openjdk.org Wed Jan 18 14:26:29 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Wed, 18 Jan 2023 14:26:29 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v2] In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 09:30:17 GMT, Ralf Schmelter wrote: >> Yes, and can reduced further with String.join >> >> return create(e, String.join(": ", e.getMessage(), addr.toString())); > > Cool, that's really short. I've updated the PR. > Hello @schmelter-sap, The javadoc of `String.join` states that it can throw a `NullPointerException` if any of the elements in `null`. As far as I can see, the `IOException` that may get thrown, probably isn't guaranteed to have a exception message, in which case this will run into a `NullPointerException`. Perhaps we should guard this code against that possibility? On JDK 19: jshell> String.join(": ", null, "bar") $3 ==> "null: bar" ------------- PR: https://git.openjdk.org/jdk/pull/11961 From jpai at openjdk.org Wed Jan 18 14:39:38 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 18 Jan 2023 14:39:38 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v6] In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 14:01:59 GMT, Ralf Schmelter wrote: >> This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. > > Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: > > Adjusted copyright headers Thank you Ralf for the updates. The current state of this PR (commit `a69d844b`) looks good to me. ------------- Marked as reviewed by jpai (Reviewer). PR: https://git.openjdk.org/jdk/pull/11961 From jpai at openjdk.org Wed Jan 18 14:39:39 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 18 Jan 2023 14:39:39 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v2] In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 14:23:55 GMT, Daniel Fuchs wrote: >> Cool, that's really short. I've updated the PR. > >> Hello @schmelter-sap, The javadoc of `String.join` states that it can throw a `NullPointerException` if any of the elements in `null`. As far as I can see, the `IOException` that may get thrown, probably isn't guaranteed to have a exception message, in which case this will run into a `NullPointerException`. Perhaps we should guard this code against that possibility? > > On JDK 19: > > > jshell> String.join(": ", null, "bar") > $3 ==> "null: bar" > > > > As long as the delimiter is not null and the vararg array itself is not null then NPE will not be thrown... > > https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/String.html#join(java.lang.CharSequence,java.lang.CharSequence...) @dfuch, you are right - it looks like the implementation of that API contradicts the javadoc. So I think it might end up being a CSR to update the javadoc to match the current implementation of `String.join()`. Given this, plus what Alan stated about the exception message being non-null in the context of this code, I think what Ralf currently has in this PR, is OK. ------------- PR: https://git.openjdk.org/jdk/pull/11961 From dfuchs at openjdk.org Wed Jan 18 14:39:40 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Wed, 18 Jan 2023 14:39:40 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v2] In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 14:31:30 GMT, Jaikiran Pai wrote: >>> Hello @schmelter-sap, The javadoc of `String.join` states that it can throw a `NullPointerException` if any of the elements in `null`. As far as I can see, the `IOException` that may get thrown, probably isn't guaranteed to have a exception message, in which case this will run into a `NullPointerException`. Perhaps we should guard this code against that possibility? >> >> On JDK 19: >> >> >> jshell> String.join(": ", null, "bar") >> $3 ==> "null: bar" >> >> >> >> As long as the delimiter is not null and the vararg array itself is not null then NPE will not be thrown... >> >> https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/String.html#join(java.lang.CharSequence,java.lang.CharSequence...) > > @dfuch, you are right - it looks like the implementation of that API contradicts the javadoc. So I think it might end up being a CSR to update the javadoc to match the current implementation of `String.join()`. Given this, plus what Alan stated about the exception message being non-null in the context of this code, I think what Ralf currently has in this PR, is OK. No the API documentation is indeed correct, it will throw if either the delimiter or the vararg array is null :-) And yes - I agree that what Ralf has is OK. FWIW the previous code would also have inserted "null" if the message had been null. ------------- PR: https://git.openjdk.org/jdk/pull/11961 From jpai at openjdk.org Wed Jan 18 14:39:41 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 18 Jan 2023 14:39:41 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v2] In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 14:32:56 GMT, Daniel Fuchs wrote: > No the API documentation is indeed correct, it will throw if either the delimiter or the vararg array is null :-) Ah! I see the distinction now :) ------------- PR: https://git.openjdk.org/jdk/pull/11961 From dfuchs at openjdk.org Wed Jan 18 14:48:33 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Wed, 18 Jan 2023 14:48:33 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v6] In-Reply-To: References: Message-ID: <_pVPFTDQM3a5aVXb4YUaXh6ui5anuOq4RSuG9r12uEQ=.ab6f31af-f6df-47be-847b-17eac8b83e57@github.com> On Wed, 18 Jan 2023 14:01:59 GMT, Ralf Schmelter wrote: >> This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. > > Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: > > Adjusted copyright headers Marked as reviewed by dfuchs (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/11961 From smarks at openjdk.org Wed Jan 18 18:50:16 2023 From: smarks at openjdk.org (Stuart Marks) Date: Wed, 18 Jan 2023 18:50:16 GMT Subject: RFR: JDK-8300133: Use generalized see and link tags in core libs [v2] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 22:54:47 GMT, Joe Darcy wrote: >> With generalized see and link tags that can refer to anchors (JDK-8200337), the see and link tags in core libraries should be updated to use this feature when possible. This PR covers such updates for java.base. > > Joe Darcy has updated the pull request incrementally with one additional commit since the last revision: > > Fix typo found in code review. Changes in collections look good. I think there are a bunch of other places where this could be used, but fixing up optional-restrictions is a good start. ------------- Marked as reviewed by smarks (Reviewer). PR: https://git.openjdk.org/jdk/pull/12000 From darcy at openjdk.org Wed Jan 18 18:57:23 2023 From: darcy at openjdk.org (Joe Darcy) Date: Wed, 18 Jan 2023 18:57:23 GMT Subject: Integrated: JDK-8300133: Use generalized see and link tags in core libs In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 21:30:06 GMT, Joe Darcy wrote: > With generalized see and link tags that can refer to anchors (JDK-8200337), the see and link tags in core libraries should be updated to use this feature when possible. This PR covers such updates for java.base. This pull request has now been integrated. Changeset: 7bf0d146 Author: Joe Darcy URL: https://git.openjdk.org/jdk/commit/7bf0d1465e73d83aae30f1cd9fd318af9e9c1b70 Stats: 107 lines in 10 files changed: 0 ins; 19 del; 88 mod 8300133: Use generalized see and link tags in core libs Reviewed-by: jjg, mchung, naoto, smarks ------------- PR: https://git.openjdk.org/jdk/pull/12000 From jwilhelm at openjdk.org Wed Jan 18 22:07:58 2023 From: jwilhelm at openjdk.org (Jesper Wilhelmsson) Date: Wed, 18 Jan 2023 22:07:58 GMT Subject: RFR: Merge jdk20 Message-ID: Forwardport JDK 20 -> JDK 21 ------------- Commit messages: - Merge remote-tracking branch 'jdk20/master' into Merge_jdk20 - 8300275: SegmentScope.isAccessibleBy returning incorrect values - 8300195: Fall-through issue occurs when using record pattern in switch statements - 8295723: security/infra/wycheproof/RunWycheproof.java fails with Assertion Error - 8295687: Better BMP bounds - 8293742: Better Banking of Sounds - 8293554: Enhanced DH Key Exchanges - 8287411: Enhance DTLS Performance - 8293717: Objective view of ObjectView - 8293734: Improve BMP image handling - ... and 5 more: https://git.openjdk.org/jdk/compare/8b70c432...77fb81ec The webrevs contain the adjustments done while merging with regards to each parent branch: - master: https://webrevs.openjdk.org/?repo=jdk&pr=12085&range=00.0 - jdk20: https://webrevs.openjdk.org/?repo=jdk&pr=12085&range=00.1 Changes: https://git.openjdk.org/jdk/pull/12085/files Stats: 564 lines in 27 files changed: 332 ins; 117 del; 115 mod Patch: https://git.openjdk.org/jdk/pull/12085.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12085/head:pull/12085 PR: https://git.openjdk.org/jdk/pull/12085 From jwilhelm at openjdk.org Wed Jan 18 23:32:35 2023 From: jwilhelm at openjdk.org (Jesper Wilhelmsson) Date: Wed, 18 Jan 2023 23:32:35 GMT Subject: Integrated: Merge jdk20 In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 21:56:13 GMT, Jesper Wilhelmsson wrote: > Forwardport JDK 20 -> JDK 21 This pull request has now been integrated. Changeset: fc9f8baf Author: Jesper Wilhelmsson URL: https://git.openjdk.org/jdk/commit/fc9f8baf56a8888362ad60d0e6dc8953690b80d3 Stats: 564 lines in 27 files changed: 332 ins; 117 del; 115 mod Merge ------------- PR: https://git.openjdk.org/jdk/pull/12085 From jpai at openjdk.org Fri Jan 20 09:15:38 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Fri, 20 Jan 2023 09:15:38 GMT Subject: RFR: 8299827: Add resolved IP address in connection exception for sockets [v6] In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 14:01:59 GMT, Ralf Schmelter wrote: >> This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. > > Ralf Schmelter has updated the pull request incrementally with one additional commit since the last revision: > > Adjusted copyright headers Hello Ralf, this PR is now ready to be merged. Whenever you are ready, please initiate a `/integrate` command so that one of us can sponsor this change for you. ------------- PR: https://git.openjdk.org/jdk/pull/11961 From dfuchs at openjdk.org Fri Jan 20 09:26:42 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Fri, 20 Jan 2023 09:26:42 GMT Subject: Integrated: 8300172: java/net/httpclient/MappingResponseSubscriber.java failed with java.net.ConnectException In-Reply-To: References: Message-ID: On Mon, 16 Jan 2023 18:08:29 GMT, Daniel Fuchs wrote: > The MappingResponseSubscriber test has been observed failing on windows in our CI due to a ConnectException. > I am suspecting that some kind of connection limit enforced by the system has been reached. > We can see from the log that the TCP connection has failed, been retried, and failed again. > Previous connections to the same server seem to have succeeded. > > Modifying the test to wait after previous clients have been GC'ed before opening the next one could alleviate the situation. This pull request has now been integrated. Changeset: 49d60fee Author: Daniel Fuchs URL: https://git.openjdk.org/jdk/commit/49d60fee49b9f5f7182dcd1557d9b2f886901100 Stats: 25 lines in 1 file changed: 23 ins; 0 del; 2 mod 8300172: java/net/httpclient/MappingResponseSubscriber.java failed with java.net.ConnectException Reviewed-by: jpai ------------- PR: https://git.openjdk.org/jdk/pull/12013 From duke at openjdk.org Fri Jan 20 16:00:52 2023 From: duke at openjdk.org (Darragh Clarke) Date: Fri, 20 Jan 2023 16:00:52 GMT Subject: RFR: 8299863: URLFromURITest.java should import org.junit.jupiter.api.Test Message-ID: <-rwHN0AI25VBn_M469YETtxK3KOa1Ttu4uU8ce8Kkcc=.459f5f4c-f4e3-49fe-9f91-223c0a01f6d0@github.com> URLFromURITest.java was mixing JUnit 4 and Jupiter APIs, this is just a simple cleanup to swap it to use only Jupiter. I looked around to see if there were any other tests affected but this seems to be the only one. ------------- Commit messages: - updated to use org.junit.jupiter.api.test to match the rest of the junit imports Changes: https://git.openjdk.org/jdk/pull/12117/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12117&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8299863 Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/12117.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12117/head:pull/12117 PR: https://git.openjdk.org/jdk/pull/12117 From dfuchs at openjdk.org Fri Jan 20 16:07:14 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Fri, 20 Jan 2023 16:07:14 GMT Subject: RFR: 8299863: URLFromURITest.java should import org.junit.jupiter.api.Test In-Reply-To: <-rwHN0AI25VBn_M469YETtxK3KOa1Ttu4uU8ce8Kkcc=.459f5f4c-f4e3-49fe-9f91-223c0a01f6d0@github.com> References: <-rwHN0AI25VBn_M469YETtxK3KOa1Ttu4uU8ce8Kkcc=.459f5f4c-f4e3-49fe-9f91-223c0a01f6d0@github.com> Message-ID: On Fri, 20 Jan 2023 15:51:52 GMT, Darragh Clarke wrote: > URLFromURITest.java was mixing JUnit 4 and Jupiter APIs, this is just a simple cleanup to swap it to use only Jupiter. > > I looked around to see if there were any other tests affected but this seems to be the only one. LGTM. Thanks for taking that one on @DarraghClarke - and thanks for looking around for other occurrences too. @sormuras does that look good to you too? ------------- Marked as reviewed by dfuchs (Reviewer). PR: https://git.openjdk.org/jdk/pull/12117 From cstein at openjdk.org Fri Jan 20 16:10:41 2023 From: cstein at openjdk.org (Christian Stein) Date: Fri, 20 Jan 2023 16:10:41 GMT Subject: RFR: 8299863: URLFromURITest.java should import org.junit.jupiter.api.Test In-Reply-To: <-rwHN0AI25VBn_M469YETtxK3KOa1Ttu4uU8ce8Kkcc=.459f5f4c-f4e3-49fe-9f91-223c0a01f6d0@github.com> References: <-rwHN0AI25VBn_M469YETtxK3KOa1Ttu4uU8ce8Kkcc=.459f5f4c-f4e3-49fe-9f91-223c0a01f6d0@github.com> Message-ID: On Fri, 20 Jan 2023 15:51:52 GMT, Darragh Clarke wrote: > URLFromURITest.java was mixing JUnit 4 and Jupiter APIs, this is just a simple cleanup to swap it to use only Jupiter. > > I looked around to see if there were any other tests affected but this seems to be the only one. ? ------------- Marked as reviewed by cstein (Committer). PR: https://git.openjdk.org/jdk/pull/12117 From rschmelter at openjdk.org Fri Jan 20 16:40:22 2023 From: rschmelter at openjdk.org (Ralf Schmelter) Date: Fri, 20 Jan 2023 16:40:22 GMT Subject: Integrated: 8299827: Add resolved IP address in connection exception for sockets In-Reply-To: References: Message-ID: On Thu, 12 Jan 2023 08:21:35 GMT, Ralf Schmelter wrote: > This change adds the resolved IP address to the exception text of a failed socket connection. This helps if the connection failed because of stale DNS entries. This pull request has now been integrated. Changeset: 92d8326e Author: Ralf Schmelter URL: https://git.openjdk.org/jdk/commit/92d8326e4037605897d7c4eb4b3edb63a2fc11b0 Stats: 18 lines in 2 files changed: 3 ins; 10 del; 5 mod 8299827: Add resolved IP address in connection exception for sockets Reviewed-by: alanb, vtewari, jpai, dfuchs ------------- PR: https://git.openjdk.org/jdk/pull/11961 From duke at openjdk.org Fri Jan 20 16:41:17 2023 From: duke at openjdk.org (Darragh Clarke) Date: Fri, 20 Jan 2023 16:41:17 GMT Subject: RFR: 8299863: URLFromURITest.java should import org.junit.jupiter.api.Test In-Reply-To: <-rwHN0AI25VBn_M469YETtxK3KOa1Ttu4uU8ce8Kkcc=.459f5f4c-f4e3-49fe-9f91-223c0a01f6d0@github.com> References: <-rwHN0AI25VBn_M469YETtxK3KOa1Ttu4uU8ce8Kkcc=.459f5f4c-f4e3-49fe-9f91-223c0a01f6d0@github.com> Message-ID: On Fri, 20 Jan 2023 15:51:52 GMT, Darragh Clarke wrote: > URLFromURITest.java was mixing JUnit 4 and Jupiter APIs, this is just a simple cleanup to swap it to use only Jupiter. > > I looked around to see if there were any other tests affected but this seems to be the only one. Great, I'll hit integrate now, though I'll need someone to sponsor it after ------------- PR: https://git.openjdk.org/jdk/pull/12117 From duke at openjdk.org Fri Jan 20 17:04:05 2023 From: duke at openjdk.org (Darragh Clarke) Date: Fri, 20 Jan 2023 17:04:05 GMT Subject: Integrated: 8299863: URLFromURITest.java should import org.junit.jupiter.api.Test In-Reply-To: <-rwHN0AI25VBn_M469YETtxK3KOa1Ttu4uU8ce8Kkcc=.459f5f4c-f4e3-49fe-9f91-223c0a01f6d0@github.com> References: <-rwHN0AI25VBn_M469YETtxK3KOa1Ttu4uU8ce8Kkcc=.459f5f4c-f4e3-49fe-9f91-223c0a01f6d0@github.com> Message-ID: <3VHE9A3p4uXLpxEDXnlodxLbrSmEwmkEH6zJVm4h-bA=.c03c37b2-91d3-4553-9c38-cab70847e931@github.com> On Fri, 20 Jan 2023 15:51:52 GMT, Darragh Clarke wrote: > URLFromURITest.java was mixing JUnit 4 and Jupiter APIs, this is just a simple cleanup to swap it to use only Jupiter. > > I looked around to see if there were any other tests affected but this seems to be the only one. This pull request has now been integrated. Changeset: e8038557 Author: Darragh Clarke Committer: Daniel Fuchs URL: https://git.openjdk.org/jdk/commit/e8038557080ba686829395b49658a899bea15d35 Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod 8299863: URLFromURITest.java should import org.junit.jupiter.api.Test Reviewed-by: dfuchs, cstein ------------- PR: https://git.openjdk.org/jdk/pull/12117 From duke at openjdk.org Fri Jan 20 17:50:09 2023 From: duke at openjdk.org (Darragh Clarke) Date: Fri, 20 Jan 2023 17:50:09 GMT Subject: RFR: 8300176: URLEncoder/URLDecoder static fields should be private static final Message-ID: Made the `static` fields `private static final`, updated the naming as well to reflect this. This meant I updated `URLDecoder` to set the `DEFAULT_ENCODING_NAME` itself since it had been previously getting it from `URLEncoder`. Since these fields are only referenced from inside the classes nothing else needed updated ------------- Commit messages: - updated fields to be private static final, updated naming to match Changes: https://git.openjdk.org/jdk/pull/12122/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12122&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8300176 Stats: 28 lines in 2 files changed: 6 ins; 0 del; 22 mod Patch: https://git.openjdk.org/jdk/pull/12122.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12122/head:pull/12122 PR: https://git.openjdk.org/jdk/pull/12122 From stsypanov at openjdk.org Sat Jan 21 17:57:04 2023 From: stsypanov at openjdk.org (Sergey Tsypanov) Date: Sat, 21 Jan 2023 17:57:04 GMT Subject: RFR: 8300176: URLEncoder/URLDecoder static fields should be private static final In-Reply-To: References: Message-ID: On Fri, 20 Jan 2023 17:41:55 GMT, Darragh Clarke wrote: > Made the `static` fields `private static final`, updated the naming as well to reflect this. > > This meant I updated `URLDecoder` to set the `DEFAULT_ENCODING_NAME` itself since it had been previously getting it from `URLEncoder`. > > Since these fields are only referenced from inside the classes nothing else needed updated src/java.base/share/classes/java/net/URLDecoder.java line 97: > 95: > 96: static { > 97: DEFAULT_ENCODING_NAME = StaticProperty.fileEncoding(); Wouldn't it be more brief to move initializer to field declaration? ------------- PR: https://git.openjdk.org/jdk/pull/12122 From redestad at openjdk.org Sun Jan 22 12:57:03 2023 From: redestad at openjdk.org (Claes Redestad) Date: Sun, 22 Jan 2023 12:57:03 GMT Subject: RFR: 8300176: URLEncoder/URLDecoder static fields should be private static final In-Reply-To: References: Message-ID: On Fri, 20 Jan 2023 17:41:55 GMT, Darragh Clarke wrote: > Made the `static` fields `private static final`, updated the naming as well to reflect this. > > This meant I updated `URLDecoder` to set the `DEFAULT_ENCODING_NAME` itself since it had been previously getting it from `URLEncoder`. > > Since these fields are only referenced from inside the classes nothing else needed updated This looks OK to me, though as @stsypanov notes initialization of `DEFAULT_ENCODING_NAME` can be further simplified. There's an existing microbenchmark, `TestEncodeDecode`, that might be affected by these changes. It'd be interesting to get some data on before/after. Pre-existing, but I'll also note that the `URLEncoder::DONT_NEED_ENCODING` could be constructed as `new BitSet(128)`: all set bits are in the ASCII range (0-127). Could be a win to trim it down. ------------- Marked as reviewed by redestad (Reviewer). PR: https://git.openjdk.org/jdk/pull/12122 From redestad at openjdk.org Sun Jan 22 19:24:06 2023 From: redestad at openjdk.org (Claes Redestad) Date: Sun, 22 Jan 2023 19:24:06 GMT Subject: RFR: 8300176: URLEncoder/URLDecoder static fields should be private static final In-Reply-To: References: Message-ID: On Fri, 20 Jan 2023 17:41:55 GMT, Darragh Clarke wrote: > Made the `static` fields `private static final`, updated the naming as well to reflect this. > > This meant I updated `URLDecoder` to set the `DEFAULT_ENCODING_NAME` itself since it had been previously getting it from `URLEncoder`. > > Since these fields are only referenced from inside the classes nothing else needed updated src/java.base/share/classes/java/net/URLEncoder.java line 124: > 122: DONT_NEED_ENCODING = new BitSet(256); > 123: int i; > 124: for (i = 'a'; i <= 'z'; i++) { These three for-loops could be simplified to: DONT_NEED_ENCODING.set('a', 'z' + 1); DONT_NEED_ENCODING.set('A', 'Z' + 1); DONT_NEED_ENCODING.set('0', '9' + 1); ------------- PR: https://git.openjdk.org/jdk/pull/12122 From dholmes at openjdk.org Mon Jan 23 03:24:47 2023 From: dholmes at openjdk.org (David Holmes) Date: Mon, 23 Jan 2023 03:24:47 GMT Subject: [jdk20] RFR: 8290919: Update nroff pages in JDK 20 before RC Message-ID: There was one missing update in javac.1 from: [JDK-8245246](https://bugs.openjdk.org/browse/JDK-8245246): Deprecate -profile option in javac otherwise the change is limited to dropping the "-ea". Thanks. ------------- Commit messages: - Merge branch 'master' into 8290919-manpages - 8290919: Update nroff pages in JDK 20 before RC Changes: https://git.openjdk.org/jdk20/pull/112/files Webrev: https://webrevs.openjdk.org/?repo=jdk20&pr=112&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8290919 Stats: 29 lines in 28 files changed: 1 ins; 0 del; 28 mod Patch: https://git.openjdk.org/jdk20/pull/112.diff Fetch: git fetch https://git.openjdk.org/jdk20 pull/112/head:pull/112 PR: https://git.openjdk.org/jdk20/pull/112 From iris at openjdk.org Mon Jan 23 07:18:06 2023 From: iris at openjdk.org (Iris Clark) Date: Mon, 23 Jan 2023 07:18:06 GMT Subject: [jdk20] RFR: 8290919: Update nroff pages in JDK 20 before RC In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 02:59:42 GMT, David Holmes wrote: > There was one missing update in javac.1 from: > > [JDK-8245246](https://bugs.openjdk.org/browse/JDK-8245246): Deprecate -profile option in javac > > otherwise the change is limited to dropping the "-ea". > > Thanks. Marked as reviewed by iris (Reviewer). ------------- PR: https://git.openjdk.org/jdk20/pull/112 From alanb at openjdk.org Mon Jan 23 07:35:07 2023 From: alanb at openjdk.org (Alan Bateman) Date: Mon, 23 Jan 2023 07:35:07 GMT Subject: [jdk20] RFR: 8290919: Update nroff pages in JDK 20 before RC In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 02:59:42 GMT, David Holmes wrote: > There was one missing update in javac.1 from: > > [JDK-8245246](https://bugs.openjdk.org/browse/JDK-8245246): Deprecate -profile option in javac > > otherwise the change is limited to dropping the "-ea". > > Thanks. Marked as reviewed by alanb (Reviewer). ------------- PR: https://git.openjdk.org/jdk20/pull/112 From dholmes at openjdk.org Mon Jan 23 07:39:08 2023 From: dholmes at openjdk.org (David Holmes) Date: Mon, 23 Jan 2023 07:39:08 GMT Subject: [jdk20] RFR: 8290919: Update nroff pages in JDK 20 before RC In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 07:15:08 GMT, Iris Clark wrote: >> There was one missing update in javac.1 from: >> >> [JDK-8245246](https://bugs.openjdk.org/browse/JDK-8245246): Deprecate -profile option in javac >> >> otherwise the change is limited to dropping the "-ea". >> >> Thanks. > > Marked as reviewed by iris (Reviewer). Thanks for the reviews @irisclark and @AlanBateman ! ------------- PR: https://git.openjdk.org/jdk20/pull/112 From dholmes at openjdk.org Mon Jan 23 07:53:05 2023 From: dholmes at openjdk.org (David Holmes) Date: Mon, 23 Jan 2023 07:53:05 GMT Subject: [jdk20] Integrated: 8290919: Update nroff pages in JDK 20 before RC In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 02:59:42 GMT, David Holmes wrote: > There was one missing update in javac.1 from: > > [JDK-8245246](https://bugs.openjdk.org/browse/JDK-8245246): Deprecate -profile option in javac > > otherwise the change is limited to dropping the "-ea". > > Thanks. This pull request has now been integrated. Changeset: fd752178 Author: David Holmes URL: https://git.openjdk.org/jdk20/commit/fd752178e364fb5deeec062bef3dde1fea1dcbe3 Stats: 29 lines in 28 files changed: 1 ins; 0 del; 28 mod 8290919: Update nroff pages in JDK 20 before RC Reviewed-by: iris, alanb ------------- PR: https://git.openjdk.org/jdk20/pull/112 From ccleary at openjdk.org Mon Jan 23 09:41:44 2023 From: ccleary at openjdk.org (Conor Cleary) Date: Mon, 23 Jan 2023 09:41:44 GMT Subject: RFR: 8287134: HttpURLConnection chunked streaming mode doesn't enforce specified size Message-ID: ### **Description** When using `HttpURLConnection::setChunkedStreamingMode()`, the current documentation does not make it clear that the `chunklen` parameter refers to the amount of bytes sent on the wire per HTTP/1.1 chunk and _not_ the payload length per chunk. The `chunklen` parameter takes into account the bytes used for the chunk size header, two CRLF characters and the possible payload length inclusively. ### **Summary of Changes & Justification** The API text has been updated to reflect the actual behavior of the method as described above to avoid a similar bug being submitted in the future and to make it clear what the `chunklen` parameter specifies. This change will require a csr. ------------- Commit messages: - 8287134: HttpURLConnection chunked streaming mode doesn't enforce specified size Changes: https://git.openjdk.org/jdk/pull/12137/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12137&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8287134 Stats: 5 lines in 1 file changed: 2 ins; 0 del; 3 mod Patch: https://git.openjdk.org/jdk/pull/12137.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12137/head:pull/12137 PR: https://git.openjdk.org/jdk/pull/12137 From ccleary at openjdk.org Mon Jan 23 09:41:44 2023 From: ccleary at openjdk.org (Conor Cleary) Date: Mon, 23 Jan 2023 09:41:44 GMT Subject: RFR: 8287134: HttpURLConnection chunked streaming mode doesn't enforce specified size In-Reply-To: References: Message-ID: <_p_68PL8uIMMWBCccCJzV_B0inebFf3uBjiwkviNv-Y=.a3c2691b-c2d5-45dd-97d9-4a5add7f1353@github.com> On Mon, 23 Jan 2023 09:04:58 GMT, Conor Cleary wrote: > ### **Description** > When using `HttpURLConnection::setChunkedStreamingMode()`, the current documentation does not make it clear that the `chunklen` parameter refers to the amount of bytes sent on the wire per HTTP/1.1 chunk and _not_ the payload length per chunk. The `chunklen` parameter takes into account the bytes used for the chunk size header, two CRLF characters and the possible payload length inclusively. > > ### **Summary of Changes & Justification** > The API text has been updated to reflect the actual behavior of the method as described above to avoid a similar bug being submitted in the future and to make it clear what the `chunklen` parameter specifies. > > This change will require a csr. A CSR will be required to be submitted for this change. I will create this and allow for a review period of this PR before finalizing it. ------------- PR: https://git.openjdk.org/jdk/pull/12137 From ccleary at openjdk.org Mon Jan 23 10:34:08 2023 From: ccleary at openjdk.org (Conor Cleary) Date: Mon, 23 Jan 2023 10:34:08 GMT Subject: RFR: 8287134: HttpURLConnection chunked streaming mode doesn't enforce specified size In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 09:04:58 GMT, Conor Cleary wrote: > ### **Description** > When using `HttpURLConnection::setChunkedStreamingMode()`, the current documentation does not make it clear that the `chunklen` parameter refers to the amount of bytes sent on the wire per HTTP/1.1 chunk and _not_ the payload length per chunk. The `chunklen` parameter takes into account the bytes used for the chunk size header, two CRLF characters and the possible payload length inclusively. > > ### **Summary of Changes & Justification** > The API text has been updated to reflect the actual behavior of the method as described above to avoid a similar bug being submitted in the future and to make it clear what the `chunklen` parameter specifies. > > This change will require a csr. A related CSR has been created here: https://bugs.openjdk.org/browse/JDK-8300848 Seeking review on that as well before moving forward. ------------- PR: https://git.openjdk.org/jdk/pull/12137 From michaelm at openjdk.org Mon Jan 23 11:43:05 2023 From: michaelm at openjdk.org (Michael McMahon) Date: Mon, 23 Jan 2023 11:43:05 GMT Subject: RFR: 8287134: HttpURLConnection chunked streaming mode doesn't enforce specified size In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 09:04:58 GMT, Conor Cleary wrote: > ### **Description** > When using `HttpURLConnection::setChunkedStreamingMode()`, the current documentation does not make it clear that the `chunklen` parameter refers to the amount of bytes sent on the wire per HTTP/1.1 chunk and _not_ the payload length per chunk. The `chunklen` parameter takes into account the bytes used for the chunk size header, two CRLF characters and the possible payload length inclusively. > > ### **Summary of Changes & Justification** > The API text has been updated to reflect the actual behavior of the method as described above to avoid a similar bug being submitted in the future and to make it clear what the `chunklen` parameter specifies. > > This change will require a csr. src/java.base/share/classes/java/net/HttpURLConnection.java line 285: > 283: * and a minimum payload length of 1 byte. If chunklen is less > 284: * than or equal to 5, a default value will be used. > 285: * I'd suggest something like this: chunklen The number of bytes to be written in each chunk, including the chunk header as a hexadecimal string (minimum of 1 byte), two CRLF's (4 bytes) and a minimum payload length of 1 byte. If chunklen is less than or equal to 5, a higher default value will be used. ------------- PR: https://git.openjdk.org/jdk/pull/12137 From ccleary at openjdk.org Mon Jan 23 12:29:16 2023 From: ccleary at openjdk.org (Conor Cleary) Date: Mon, 23 Jan 2023 12:29:16 GMT Subject: RFR: 8287134: HttpURLConnection chunked streaming mode doesn't enforce specified size [v2] In-Reply-To: References: Message-ID: > ### **Description** > When using `HttpURLConnection::setChunkedStreamingMode()`, the current documentation does not make it clear that the `chunklen` parameter refers to the amount of bytes sent on the wire per HTTP/1.1 chunk and _not_ the payload length per chunk. The `chunklen` parameter takes into account the bytes used for the chunk size header, two CRLF characters and the possible payload length inclusively. > > ### **Summary of Changes & Justification** > The API text has been updated to reflect the actual behavior of the method as described above to avoid a similar bug being submitted in the future and to make it clear what the `chunklen` parameter specifies. > > This change will require a csr. Conor Cleary has updated the pull request incrementally with one additional commit since the last revision: 8287134: Shortened text and corrected typo ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12137/files - new: https://git.openjdk.org/jdk/pull/12137/files/93588aec..38de2297 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12137&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12137&range=00-01 Stats: 5 lines in 1 file changed: 0 ins; 0 del; 5 mod Patch: https://git.openjdk.org/jdk/pull/12137.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12137/head:pull/12137 PR: https://git.openjdk.org/jdk/pull/12137 From ccleary at openjdk.org Mon Jan 23 12:29:20 2023 From: ccleary at openjdk.org (Conor Cleary) Date: Mon, 23 Jan 2023 12:29:20 GMT Subject: RFR: 8287134: HttpURLConnection chunked streaming mode doesn't enforce specified size [v2] In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 11:40:35 GMT, Michael McMahon wrote: >> Conor Cleary has updated the pull request incrementally with one additional commit since the last revision: >> >> 8287134: Shortened text and corrected typo > > src/java.base/share/classes/java/net/HttpURLConnection.java line 285: > >> 283: * and a minimum payload length of 1 byte. If chunklen is less >> 284: * than or equal to 5, a default value will be used. >> 285: * > > I'd suggest something like this: > > chunklen The number of bytes to be written in > each chunk, including the chunk header as a > hexadecimal string (minimum of 1 byte), two CRLF's (4 bytes) > and a minimum payload length of 1 byte. If chunklen is less > than or equal to 5, a higher default value will be used. Thanks @Michael-Mc-Mahon, I updated the text with respect to your suggestion there (which was definitely a bit more cleared than mine) and corrected my incorrect spelling of hexadecimal in my most recent changes just now. ------------- PR: https://git.openjdk.org/jdk/pull/12137 From dfuchs at openjdk.org Mon Jan 23 13:42:07 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Mon, 23 Jan 2023 13:42:07 GMT Subject: RFR: 8287134: HttpURLConnection chunked streaming mode doesn't enforce specified size [v2] In-Reply-To: References: Message-ID: <04buObO6bTAsxRmN_naS4r9E-2Lybh8FnVtaWfNoGcY=.a0ce7aae-a20a-4bc7-bcde-46ffafccd209@github.com> On Mon, 23 Jan 2023 12:29:16 GMT, Conor Cleary wrote: >> ### **Description** >> When using `HttpURLConnection::setChunkedStreamingMode()`, the current documentation does not make it clear that the `chunklen` parameter refers to the amount of bytes sent on the wire per HTTP/1.1 chunk and _not_ the payload length per chunk. The `chunklen` parameter takes into account the bytes used for the chunk size header, two CRLF characters and the possible payload length inclusively. >> >> ### **Summary of Changes & Justification** >> The API text has been updated to reflect the actual behavior of the method as described above to avoid a similar bug being submitted in the future and to make it clear what the `chunklen` parameter specifies. >> >> This change will require a csr. > > Conor Cleary has updated the pull request incrementally with one additional commit since the last revision: > > 8287134: Shortened text and corrected typo The new text looks good to me. ------------- Marked as reviewed by dfuchs (Reviewer). PR: https://git.openjdk.org/jdk/pull/12137 From ccleary at openjdk.org Mon Jan 23 14:58:09 2023 From: ccleary at openjdk.org (Conor Cleary) Date: Mon, 23 Jan 2023 14:58:09 GMT Subject: RFR: 8296410: HttpClient throws java.io.IOException: no statuscode in response for HTTP2 In-Reply-To: References: <7AIQEkQAJ8gNZR7Quz3-lTxlUkMNFdTSSlp3s9cT0Cs=.7be692db-87fc-49eb-834b-db86566ff2b1@github.com> Message-ID: On Wed, 18 Jan 2023 11:47:06 GMT, Conor Cleary wrote: > The changes in this PR look good to me. While looking at the source code, I noticed that the `Stream` class has a `PushedStream` nested class which too has a similar implementation in `handleResponse()`. I haven't yet checked the spec related to this; do you know if this code too will need a similar fix? The original situation for a regular request-response in http2 was caused by a server responding to a client request with response headers that included only a code 200 status with no flags set and the related data. This was then followed by trailing headers with both the END_STREAM and END_HEADERS flags set with an empty header block (though the contents of the block aren't of concern here). Now, the Push Promise version of this situation is a bit different. A Push Promise frame is sent to the client containing all expected details such as the promisedStreamId, request path etc. However if we try mirror the previous situation by _not_ including an END_HEADERS flag in the Push Promise frame and attempting to send a trailing HEADERS frame, the HttpClient correcly throws a protocol error specifying that the client `Expected a Continuation frame but received HEADERS`. This is behavior defined in [section 6.6. of RFC7540: HTTP/2](https://www.rfc-editor.org/rfc/rfc7540#section-6.6). The PUSH_PROMISE frame defines the following flags: END_HEADERS (0x4): When set, bit 2 indicates that this frame contains an entire header block (Section 4.3) and is not followed by any CONTINUATION frames. A PUSH_PROMISE frame without the END_HEADERS flag set MUST be followed by a CONTINUATION frame for the same stream. A receiver MUST treat the receipt of any other type of frame or a frame on a different stream as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. With this in mind, I would argue that in the case of `PushedStream::handleResponse` no changes are required as the behavior is quite well defined and strict when it comes to testing what the HttpClient will allow. One interesting side note is that END_STREAM is not strictly speaking a defined flag for PUSH_PROMISE frames. Interested to see what reviewers have to say about that analysis or if there are any mistakes in my thinking, it was quite a tricky one to wrap my head around given the differences with how Push Requests are treated by the client. ------------- PR: https://git.openjdk.org/jdk/pull/12028 From ccleary at openjdk.org Mon Jan 23 14:58:13 2023 From: ccleary at openjdk.org (Conor Cleary) Date: Mon, 23 Jan 2023 14:58:13 GMT Subject: RFR: 8296410: HttpClient throws java.io.IOException: no statuscode in response for HTTP2 In-Reply-To: References: Message-ID: On Wed, 18 Jan 2023 07:25:47 GMT, Jaikiran Pai wrote: >> ### **Description** >> With HTTP/2, a possible flow of an exchange could be that a Server responds to a simple request by sending response headers within a HEADERS frame, the requested resources and trailing headers with another HEADERS frame including the END_HEADERS and END_STREAM flags (if they were not previously given in the Response Headers). Usually an HTTP/2 client should opt-in to make use of trailing headers though this behaviour is not supoorted by default with the HttpClient. >> >> It is still possible in any case that a trailing HEADERS frame can be sent, even if the frame just carries flags and no headers specified in the header block. This edge case was causing an IOException to be thrown and the client to shut down unexpectedly. >> >> ### **Summary of Changes & Justification** >> In Stream, a means to track the state of whether or not a final status code for an exchange has been received was added to prevent the exception occuring due to a HEADERS frame with no status code arriving after response headers were received. In the case of a partial response (status codes in the 1XX range), the flag for receiving a final response code is not set until a response outside of the 1XX range is received. >> >> Lastly, if trailing headers are received, they are logged and dumped. The response headers consumer is then reset. >> >> --------- >> ### Progress >> - [ ] Change must be properly reviewed (1 review required, with at least 1 [Reviewer](https://openjdk.org/bylaws#reviewer)) >> - [x] Change must not contain extraneous whitespace >> - [x] Commit message must refer to an issue >> >> >> >> ### Reviewing >>
Using git >> >> Checkout this PR locally: \ >> `$ git fetch https://git.openjdk.org/jdk pull/12028/head:pull/12028` \ >> `$ git checkout pull/12028` >> >> Update a local copy of the PR: \ >> `$ git checkout pull/12028` \ >> `$ git pull https://git.openjdk.org/jdk pull/12028/head` >> >>
>>
Using Skara CLI tools >> >> Checkout this PR locally: \ >> `$ git pr checkout 12028` >> >> View PR using the GUI difftool: \ >> `$ git pr show -t 12028` >> >>
>>
Using diff file >> >> Download this PR as a diff file: \ >> https://git.openjdk.org/jdk/pull/12028.diff >> >>
> > test/jdk/java/net/httpclient/http2/TrailingHeadersTest.java line 2: > >> 1: /* >> 2: * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. > > Hello Conor, this appears to be a typo. Given that this is a new file, only 2023 would be relevant. I'll hold off on updating this until more discussion takes place below, for ease of VC use locally ------------- PR: https://git.openjdk.org/jdk/pull/12028 From ccleary at openjdk.org Mon Jan 23 15:03:11 2023 From: ccleary at openjdk.org (Conor Cleary) Date: Mon, 23 Jan 2023 15:03:11 GMT Subject: RFR: 8296410: HttpClient throws java.io.IOException: no statuscode in response for HTTP2 In-Reply-To: References: Message-ID: <5ZLGPzu-vq-sk_6D8IRuVq4AHGpaECtRYCU6FLpisHY=.78cd4d64-383a-44fb-b7b0-b65e9eadcf1e@github.com> On Tue, 17 Jan 2023 10:58:54 GMT, Conor Cleary wrote: > ### **Description** > With HTTP/2, a possible flow of an exchange could be that a Server responds to a simple request by sending response headers within a HEADERS frame, the requested resources and trailing headers with another HEADERS frame including the END_HEADERS and END_STREAM flags (if they were not previously given in the Response Headers). Usually an HTTP/2 client should opt-in to make use of trailing headers though this behaviour is not supoorted by default with the HttpClient. > > It is still possible in any case that a trailing HEADERS frame can be sent, even if the frame just carries flags and no headers specified in the header block. This edge case was causing an IOException to be thrown and the client to shut down unexpectedly. > > ### **Summary of Changes & Justification** > In Stream, a means to track the state of whether or not a final status code for an exchange has been received was added to prevent the exception occuring due to a HEADERS frame with no status code arriving after response headers were received. In the case of a partial response (status codes in the 1XX range), the flag for receiving a final response code is not set until a response outside of the 1XX range is received. > > Lastly, if trailing headers are received, they are logged and dumped. The response headers consumer is then reset. > > --------- > ### Progress > - [ ] Change must be properly reviewed (1 review required, with at least 1 [Reviewer](https://openjdk.org/bylaws#reviewer)) > - [x] Change must not contain extraneous whitespace > - [x] Commit message must refer to an issue > > > > ### Reviewing >
Using git > > Checkout this PR locally: \ > `$ git fetch https://git.openjdk.org/jdk pull/12028/head:pull/12028` \ > `$ git checkout pull/12028` > > Update a local copy of the PR: \ > `$ git checkout pull/12028` \ > `$ git pull https://git.openjdk.org/jdk pull/12028/head` > >
>
Using Skara CLI tools > > Checkout this PR locally: \ > `$ git pr checkout 12028` > > View PR using the GUI difftool: \ > `$ git pr show -t 12028` > >
>
Using diff file > > Download this PR as a diff file: \ > https://git.openjdk.org/jdk/pull/12028.diff > >
Semi-related, a previous fix concerning Push Promises: https://github.com/openjdk/jdk/pull/8518 ------------- PR: https://git.openjdk.org/jdk/pull/12028 From ccleary at openjdk.org Mon Jan 23 15:12:24 2023 From: ccleary at openjdk.org (Conor Cleary) Date: Mon, 23 Jan 2023 15:12:24 GMT Subject: RFR: 8287134: HttpURLConnection chunked streaming mode doesn't enforce specified size [v2] In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 12:29:16 GMT, Conor Cleary wrote: >> ### **Description** >> When using `HttpURLConnection::setChunkedStreamingMode()`, the current documentation does not make it clear that the `chunklen` parameter refers to the amount of bytes sent on the wire per HTTP/1.1 chunk and _not_ the payload length per chunk. The `chunklen` parameter takes into account the bytes used for the chunk size header, two CRLF characters and the possible payload length inclusively. >> >> ### **Summary of Changes & Justification** >> The API text has been updated to reflect the actual behavior of the method as described above to avoid a similar bug being submitted in the future and to make it clear what the `chunklen` parameter specifies. >> >> This change will require a csr. > > Conor Cleary has updated the pull request incrementally with one additional commit since the last revision: > > 8287134: Shortened text and corrected typo Thanks Daniel! The related CSR has now been updated to reflect the new text. ------------- PR: https://git.openjdk.org/jdk/pull/12137 From dfuchs at openjdk.org Mon Jan 23 15:50:11 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Mon, 23 Jan 2023 15:50:11 GMT Subject: RFR: 8296410: HttpClient throws java.io.IOException: no statuscode in response for HTTP2 In-Reply-To: References: <7AIQEkQAJ8gNZR7Quz3-lTxlUkMNFdTSSlp3s9cT0Cs=.7be692db-87fc-49eb-834b-db86566ff2b1@github.com> Message-ID: On Mon, 23 Jan 2023 14:51:57 GMT, Conor Cleary wrote: > Interested to get some other opinions on that analysis or to see if there are any mistakes in that thinking, it was quite a tricky one to wrap my head around given the differences with how Push Requests are treated by the client. I do disagree with that analysis. We're not speaking of the PUSH_PROMISE frame here, but of the HEADER frame sent on the push promise stream. When a server wants to send a push promise, it sends a PUSH_PROMISE frame on the request/response stream. This contains the stream id on which the promised push will be sent, as well as the *request headers* of the promised push. Then *on the push promise stream*, it proceeds to send the response headers of the promised push, followed by the response body (if any - but it would be surprising for a push to have no body), potentially followed by trailers. Note that this is a different stream from the original request-response stream on which the PUSH_PROMISE stream was sent, but like the request/response stream - I believe it can have trailers, though the spec is not clear about this - it only says that it "ends with a frame with the END_STREAM flag set". Like for a regular response we would expect this to be a DATA frame, but if a server has been coded to send the END_STREAM flag on an empty trailer frame, it may also happen there. ------------- PR: https://git.openjdk.org/jdk/pull/12028 From jwilhelm at openjdk.org Mon Jan 23 20:27:19 2023 From: jwilhelm at openjdk.org (Jesper Wilhelmsson) Date: Mon, 23 Jan 2023 20:27:19 GMT Subject: RFR: Merge jdk20 Message-ID: Forwardport JDK 20 -> JDK 21 ------------- Commit messages: - Merge - 8290919: Update nroff pages in JDK 20 before RC The webrevs contain the adjustments done while merging with regards to each parent branch: - master: https://webrevs.openjdk.org/?repo=jdk&pr=12150&range=00.0 - jdk20: https://webrevs.openjdk.org/?repo=jdk&pr=12150&range=00.1 Changes: https://git.openjdk.org/jdk/pull/12150/files Stats: 28 lines in 27 files changed: 1 ins; 0 del; 27 mod Patch: https://git.openjdk.org/jdk/pull/12150.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12150/head:pull/12150 PR: https://git.openjdk.org/jdk/pull/12150 From jwilhelm at openjdk.org Mon Jan 23 21:07:12 2023 From: jwilhelm at openjdk.org (Jesper Wilhelmsson) Date: Mon, 23 Jan 2023 21:07:12 GMT Subject: Integrated: Merge jdk20 In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 19:52:49 GMT, Jesper Wilhelmsson wrote: > Forwardport JDK 20 -> JDK 21 This pull request has now been integrated. Changeset: 56dc3b08 Author: Jesper Wilhelmsson URL: https://git.openjdk.org/jdk/commit/56dc3b08a62f651835c5bccca987d93ba2bb8961 Stats: 28 lines in 27 files changed: 1 ins; 0 del; 27 mod Merge ------------- PR: https://git.openjdk.org/jdk/pull/12150 From dholmes at openjdk.org Mon Jan 23 23:21:44 2023 From: dholmes at openjdk.org (David Holmes) Date: Mon, 23 Jan 2023 23:21:44 GMT Subject: RFR: 8290918: Initial nroff manpage generation for JDK 21 Message-ID: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Please review this simple update to the manpage to set the version to 21-ea. This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 Thanks. ------------- Commit messages: - 8290918: Initial nroff manpage generation for JDK 21 Changes: https://git.openjdk.org/jdk/pull/12154/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12154&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8290918 Stats: 28 lines in 27 files changed: 0 ins; 0 del; 28 mod Patch: https://git.openjdk.org/jdk/pull/12154.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12154/head:pull/12154 PR: https://git.openjdk.org/jdk/pull/12154 From lancea at openjdk.org Mon Jan 23 23:27:05 2023 From: lancea at openjdk.org (Lance Andersen) Date: Mon, 23 Jan 2023 23:27:05 GMT Subject: RFR: 8290918: Initial nroff manpage generation for JDK 21 In-Reply-To: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> References: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Message-ID: On Mon, 23 Jan 2023 22:59:22 GMT, David Holmes wrote: > Please review this simple update to the manpage to set the version to 21-ea. > > This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 > > Thanks. Marked as reviewed by lancea (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12154 From dholmes at openjdk.org Tue Jan 24 00:49:08 2023 From: dholmes at openjdk.org (David Holmes) Date: Tue, 24 Jan 2023 00:49:08 GMT Subject: RFR: 8290918: Initial nroff manpage generation for JDK 21 In-Reply-To: References: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Message-ID: On Mon, 23 Jan 2023 23:24:06 GMT, Lance Andersen wrote: >> Please review this simple update to the manpage to set the version to 21-ea. >> >> This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 >> >> Thanks. > > Marked as reviewed by lancea (Reviewer). Thanks for the review @LanceAndersen ------------- PR: https://git.openjdk.org/jdk/pull/12154 From duke at openjdk.org Tue Jan 24 00:56:11 2023 From: duke at openjdk.org (David Schlosnagle) Date: Tue, 24 Jan 2023 00:56:11 GMT Subject: RFR: 8300176: URLEncoder/URLDecoder static fields should be private static final In-Reply-To: References: Message-ID: On Fri, 20 Jan 2023 17:41:55 GMT, Darragh Clarke wrote: > Made the `static` fields `private static final`, updated the naming as well to reflect this. > > This meant I updated `URLDecoder` to set the `DEFAULT_ENCODING_NAME` itself since it had been previously getting it from `URLEncoder`. > > Since these fields are only referenced from inside the classes nothing else needed updated Curious if we could remove a couple of the static fields src/java.base/share/classes/java/net/URLDecoder.java line 99: > 97: DEFAULT_ENCODING_NAME = StaticProperty.fileEncoding(); > 98: } > 99: Can we just in-line the use of `StaticProperty.fileEncoding()` to the call site as `StaicProperty.FILE_ENCODING` is already stored in a static final field Suggestion: https://github.com/openjdk/jdk/blob/77a50105f0c4a4cb7286dda13c633f1e69295210/src/java.base/share/classes/jdk/internal/util/StaticProperty.java#L54-L74 src/java.base/share/classes/java/net/URLDecoder.java line 117: > 115: > 116: try { > 117: str = decode(s, DEFAULT_ENCODING_NAME); Suggestion: str = decode(s, StaticProperty.fileEncoding()); src/java.base/share/classes/java/net/URLEncoder.java line 82: > 80: private static final BitSet DONT_NEED_ENCODING; > 81: private static final int CASE_DIFF = ('a' - 'A'); > 82: private static final String DEFAULT_ENCODING_NAME; Similar to above, can we inline usages? Suggestion: src/java.base/share/classes/java/net/URLEncoder.java line 140: > 138: DONT_NEED_ENCODING.set('*'); > 139: > 140: DEFAULT_ENCODING_NAME = StaticProperty.fileEncoding(); Suggestion: src/java.base/share/classes/java/net/URLEncoder.java line 165: > 163: > 164: try { > 165: str = encode(s, DEFAULT_ENCODING_NAME); Suggestion: str = encode(s, StaticProperty.fileEncoding()); ------------- PR: https://git.openjdk.org/jdk/pull/12122 From iris at openjdk.org Tue Jan 24 01:32:03 2023 From: iris at openjdk.org (Iris Clark) Date: Tue, 24 Jan 2023 01:32:03 GMT Subject: RFR: 8290918: Initial nroff manpage generation for JDK 21 In-Reply-To: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> References: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Message-ID: On Mon, 23 Jan 2023 22:59:22 GMT, David Holmes wrote: > Please review this simple update to the manpage to set the version to 21-ea. > > This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 > > Thanks. Marked as reviewed by iris (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12154 From dholmes at openjdk.org Tue Jan 24 05:42:02 2023 From: dholmes at openjdk.org (David Holmes) Date: Tue, 24 Jan 2023 05:42:02 GMT Subject: RFR: 8290918: Initial nroff manpage generation for JDK 21 In-Reply-To: References: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Message-ID: On Tue, 24 Jan 2023 01:28:53 GMT, Iris Clark wrote: >> Please review this simple update to the manpage to set the version to 21-ea. >> >> This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 >> >> Thanks. > > Marked as reviewed by iris (Reviewer). Thanks for the review @irisclark ! ------------- PR: https://git.openjdk.org/jdk/pull/12154 From darcy at openjdk.org Tue Jan 24 05:57:04 2023 From: darcy at openjdk.org (Joe Darcy) Date: Tue, 24 Jan 2023 05:57:04 GMT Subject: RFR: 8290918: Initial nroff manpage generation for JDK 21 In-Reply-To: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> References: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Message-ID: On Mon, 23 Jan 2023 22:59:22 GMT, David Holmes wrote: > Please review this simple update to the manpage to set the version to 21-ea. > > This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 > > Thanks. Marked as reviewed by darcy (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12154 From jpai at openjdk.org Tue Jan 24 06:16:28 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Tue, 24 Jan 2023 06:16:28 GMT Subject: RFR: 8295944: Move the Http2TestServer and related classes into a package of its own Message-ID: Can I please get a review of this change which addresses https://bugs.openjdk.org/browse/JDK-8295944? As noted in the issue, the HttpClient testing helper infrastructure code resides in a default (unnamed) packages within the test hierarchy. The commit in this PR moves those classes into a specific package. The tests have been updated to refer to them correctly with proper package name references. Additionally as noted in the issue, the `@modules` declaration used in the httpclient tests, were all the same and were repeated in all these tests. The commit in this PR moves those module references into the `TEST.properties` to centralize such reference. Any test which needs additional modules can then use specific `@modules` declaration in the test definition. No functional changes have been done in this PR. tier1, tier2 and tier3 testing passed after these changes. ------------- Commit messages: - fix SANTest which was missed out from the refactoring - move out the @modules declaration from test definition, to TEST.properties - 8295944: Move the Http2TestServer and related classes into a package of its own Changes: https://git.openjdk.org/jdk/pull/12160/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12160&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8295944 Stats: 1092 lines in 135 files changed: 297 ins; 335 del; 460 mod Patch: https://git.openjdk.org/jdk/pull/12160.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12160/head:pull/12160 PR: https://git.openjdk.org/jdk/pull/12160 From dholmes at openjdk.org Tue Jan 24 06:31:11 2023 From: dholmes at openjdk.org (David Holmes) Date: Tue, 24 Jan 2023 06:31:11 GMT Subject: RFR: 8290918: Initial nroff manpage generation for JDK 21 In-Reply-To: References: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Message-ID: On Tue, 24 Jan 2023 05:54:44 GMT, Joe Darcy wrote: >> Please review this simple update to the manpage to set the version to 21-ea. >> >> This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 >> >> Thanks. > > Marked as reviewed by darcy (Reviewer). Thanks for the review @jddarcy ! I think that suffices for this trivial change. ------------- PR: https://git.openjdk.org/jdk/pull/12154 From dholmes at openjdk.org Tue Jan 24 06:31:13 2023 From: dholmes at openjdk.org (David Holmes) Date: Tue, 24 Jan 2023 06:31:13 GMT Subject: Integrated: 8290918: Initial nroff manpage generation for JDK 21 In-Reply-To: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> References: <_l9LWouUV22whyL4PTf1esOed9cZw1jyKKVBozovayE=.f79dbc18-b48e-4e52-8a16-f9e1b732ce50@github.com> Message-ID: On Mon, 23 Jan 2023 22:59:22 GMT, David Holmes wrote: > Please review this simple update to the manpage to set the version to 21-ea. > > This change also corrects a typo in javac.1 that was manually introduced by JDK-8300591 > > Thanks. This pull request has now been integrated. Changeset: 6dd8723f Author: David Holmes URL: https://git.openjdk.org/jdk/commit/6dd8723f66a22e626d98c74cff0b0b344a62626d Stats: 28 lines in 27 files changed: 0 ins; 0 del; 28 mod 8290918: Initial nroff manpage generation for JDK 21 Reviewed-by: lancea, iris, darcy ------------- PR: https://git.openjdk.org/jdk/pull/12154 From jpai at openjdk.org Tue Jan 24 09:59:38 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Tue, 24 Jan 2023 09:59:38 GMT Subject: RFR: 8295944: Move the Http2TestServer and related classes into a package of its own [v2] In-Reply-To: References: Message-ID: <5E30Z44CJ4M5z8pnLcd7b0E3GYwFjiCn9iyrghHFeNY=.da518784-c437-4d99-80e9-58c3e2ce20aa@github.com> > Can I please get a review of this change which addresses https://bugs.openjdk.org/browse/JDK-8295944? > > As noted in the issue, the HttpClient testing helper infrastructure code resides in a default (unnamed) packages within the test hierarchy. The commit in this PR moves those classes into a specific package. The tests have been updated to refer to them correctly with proper package name references. > Additionally as noted in the issue, the `@modules` declaration used in the httpclient tests, were all the same and were repeated in all these tests. The commit in this PR moves those module references into the `TEST.properties` to centralize such reference. Any test which needs additional modules can then use specific `@modules` declaration in the test definition. > > No functional changes have been done in this PR. > > tier1, tier2 and tier3 testing passed after these changes. Jaikiran Pai has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains four additional commits since the last revision: - merge latest from master branch - fix SANTest which was missed out from the refactoring - move out the @modules declaration from test definition, to TEST.properties - 8295944: Move the Http2TestServer and related classes into a package of its own ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12160/files - new: https://git.openjdk.org/jdk/pull/12160/files/aae2c1fb..97cbdc2e Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12160&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12160&range=00-01 Stats: 193 lines in 47 files changed: 77 ins; 10 del; 106 mod Patch: https://git.openjdk.org/jdk/pull/12160.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12160/head:pull/12160 PR: https://git.openjdk.org/jdk/pull/12160 From dfuchs at openjdk.org Tue Jan 24 12:41:28 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Tue, 24 Jan 2023 12:41:28 GMT Subject: RFR: 8295944: Move the Http2TestServer and related classes into a package of its own [v2] In-Reply-To: <5E30Z44CJ4M5z8pnLcd7b0E3GYwFjiCn9iyrghHFeNY=.da518784-c437-4d99-80e9-58c3e2ce20aa@github.com> References: <5E30Z44CJ4M5z8pnLcd7b0E3GYwFjiCn9iyrghHFeNY=.da518784-c437-4d99-80e9-58c3e2ce20aa@github.com> Message-ID: <-3bmvTZYKHK6p1ix0FyEKB3yxsoAqVLBvRfzHHWvPrg=.42cf0599-8d6a-4ca0-ad83-c2f46932db72@github.com> On Tue, 24 Jan 2023 09:59:38 GMT, Jaikiran Pai wrote: >> Can I please get a review of this change which addresses https://bugs.openjdk.org/browse/JDK-8295944? >> >> As noted in the issue, the HttpClient testing helper infrastructure code resides in a default (unnamed) packages within the test hierarchy. The commit in this PR moves those classes into a specific package. The tests have been updated to refer to them correctly with proper package name references. >> Additionally as noted in the issue, the `@modules` declaration used in the httpclient tests, were all the same and were repeated in all these tests. The commit in this PR moves those module references into the `TEST.properties` to centralize such reference. Any test which needs additional modules can then use specific `@modules` declaration in the test definition. >> >> No functional changes have been done in this PR. >> >> tier1, tier2 and tier3 testing passed after these changes. > > Jaikiran Pai has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains four additional commits since the last revision: > > - merge latest from master branch > - fix SANTest which was missed out from the refactoring > - move out the @modules declaration from test definition, to TEST.properties > - 8295944: Move the Http2TestServer and related classes into a package of its own Very nice refactoring overall. Thanks for taking that on! There are a few places where some lines should have been removed but were not. I made some suggestions. Also there are 9 classes that have kept their custom `@modules` clause because they want to access * java.base/sun.net.www * java.base/sun.net ``` I wonder if we should just add these two in TEST.properties - and then remove the `@modules` from these nine classes as well? test/jdk/java/net/httpclient/BasicRedirectTest.java line 28: > 26: * @summary Basic test for redirect and redirect policies > 27: * java.logging > 28: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/ConcurrentResponses.java line 30: > 28: * unprocessed HTTP data > 29: * java.logging > 30: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/CookieHeaderTest.java line 29: > 27: * @summary Test for multiple vs single cookie header for HTTP/2 vs HTTP/1.1 > 28: * java.logging > 29: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/CustomRequestPublisher.java line 28: > 26: * @summary Checks correct handling of Publishers that call onComplete without demand > 27: * java.logging > 28: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/ExecutorShutdown.java line 30: > 28: * new tasks while the client is still running > 29: * java.logging > 30: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest.java line 32: > 30: * policy 2: custom permission for test classes > 31: * policy 3: custom permission for test classes and httpclient > 32: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/FilePublisher/FilePublisherTest.java line 29: > 27: * @summary Confirm that HttpRequest.BodyPublishers#ofFile(Path) > 28: * assumes the default file system > 29: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/FlowAdapterPublisherTest.java line 69: > 67: * @summary Basic tests for Flow adapter Publishers > 68: * java.logging > 69: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/FlowAdapterSubscriberTest.java line 70: > 68: * @summary Basic tests for Flow adapter Subscribers > 69: * java.logging > 70: * jdk.httpserver Shouldn't these two lines be removed as well? Suggestion: test/jdk/java/net/httpclient/HeadTest.java line 29: > 27: * @summary (httpclient) Add tests for HEAD and 304 responses. > 28: * java.logging > 29: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/MaxStreams.java line 30: > 28: * > 29: * java.logging > 30: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileDownloadTest.java line 29: > 27: * @summary Confirm HttpResponse.BodySubscribers#ofFileDownload(Path) > 28: * works only with the default file system > 29: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileTest.java line 30: > 28: * works with default and non-default file systems > 29: * when SecurityManager is enabled > 30: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/PathSubscriber/BodySubscriberOfFileTest.java line 30: > 28: * works with default and non-default file systems > 29: * when SecurityManager is enabled > 30: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/RedirectMethodChange.java line 27: > 25: * @test > 26: * @summary Method change during redirection > 27: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/RedirectWithCookie.java line 28: > 26: * @summary Test for cookie handling when redirecting > 27: * java.logging > 28: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/Response1xxTest.java line 54: > 52: * @summary Tests behaviour of HttpClient when server responds with 102 or 103 status codes > 53: * java.logging > 54: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/RetryWithCookie.java line 29: > 27: * @summary Test for cookie handling when retrying after close > 28: * java.logging > 29: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/StreamingBody.java line 29: > 27: * strong (or any ) reference to the client. > 28: * java.logging > 29: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/UnauthorizedTest.java line 33: > 31: * should simply let the caller deal with the unauthorized response. > 32: * java.logging > 33: * jdk.httpserver Suggestion: test/jdk/java/net/httpclient/UserCookieTest.java line 30: > 28: * server-cookies for HTTP/2 vs HTTP/1.1 > 29: * java.logging > 30: * jdk.httpserver Suggestion: ------------- Changes requested by dfuchs (Reviewer). PR: https://git.openjdk.org/jdk/pull/12160 From dfuchs at openjdk.org Tue Jan 24 16:44:51 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Tue, 24 Jan 2023 16:44:51 GMT Subject: RFR: 8301004: httpclient: Add more debug to HttpResponseInputStream Message-ID: The AsyncExecutorShutdown test has been observed failing (rarely) in our CI. The root cause seems to be an assertion error in HttpResponseInputStream. More debug traces could help with diagnosing how we reached this assertion. ------------- Commit messages: - 8301004 Changes: https://git.openjdk.org/jdk/pull/12169/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12169&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8301004 Stats: 16 lines in 1 file changed: 14 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jdk/pull/12169.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12169/head:pull/12169 PR: https://git.openjdk.org/jdk/pull/12169 From jpai at openjdk.org Wed Jan 25 01:58:04 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 25 Jan 2023 01:58:04 GMT Subject: RFR: 8301004: httpclient: Add more debug to HttpResponseInputStream In-Reply-To: References: Message-ID: <0VKUiwWlNkDhXKMkMnmMrOjYQEbVdwt_AfnSZWdTgQg=.212d97bb-a0de-4983-b80f-8be0db941ec2@github.com> On Tue, 24 Jan 2023 16:36:42 GMT, Daniel Fuchs wrote: > The AsyncExecutorShutdown test has been observed failing (rarely) in our CI. The root cause seems to be an assertion error in HttpResponseInputStream. More debug traces could help with diagnosing how we reached this assertion. Marked as reviewed by jpai (Reviewer). Marked as reviewed by jpai (Reviewer). src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java line 565: > 563: assert buffers.remainingCapacity() > 1 > 564: : "buffers capacity: " + buffers.remainingCapacity() > 565: + "closed: " + closed + "failed: " + failed; Hello Daniel, I think a space before `closed:` and `failed:` would be good. Other than that, this looks good. ------------- PR: https://git.openjdk.org/jdk/pull/12169 From jpai at openjdk.org Wed Jan 25 06:35:14 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 25 Jan 2023 06:35:14 GMT Subject: RFR: 8295944: Move the Http2TestServer and related classes into a package of its own [v2] In-Reply-To: <5E30Z44CJ4M5z8pnLcd7b0E3GYwFjiCn9iyrghHFeNY=.da518784-c437-4d99-80e9-58c3e2ce20aa@github.com> References: <5E30Z44CJ4M5z8pnLcd7b0E3GYwFjiCn9iyrghHFeNY=.da518784-c437-4d99-80e9-58c3e2ce20aa@github.com> Message-ID: On Tue, 24 Jan 2023 09:59:38 GMT, Jaikiran Pai wrote: >> Can I please get a review of this change which addresses https://bugs.openjdk.org/browse/JDK-8295944? >> >> As noted in the issue, the HttpClient testing helper infrastructure code resides in a default (unnamed) packages within the test hierarchy. The commit in this PR moves those classes into a specific package. The tests have been updated to refer to them correctly with proper package name references. >> Additionally as noted in the issue, the `@modules` declaration used in the httpclient tests, were all the same and were repeated in all these tests. The commit in this PR moves those module references into the `TEST.properties` to centralize such reference. Any test which needs additional modules can then use specific `@modules` declaration in the test definition. >> >> No functional changes have been done in this PR. >> >> tier1, tier2 and tier3 testing passed after these changes. > > Jaikiran Pai has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains four additional commits since the last revision: > > - merge latest from master branch > - fix SANTest which was missed out from the refactoring > - move out the @modules declaration from test definition, to TEST.properties > - 8295944: Move the Http2TestServer and related classes into a package of its own Hello Daniel, > There are a few places where some lines should have been removed but were not. I made some suggestions. Thank you for catching these. These were genuine issues and were a leftover from my `@modules` removal. I've fixed these now in the updated PR. I went through all the files again and did a search (with a different search term this time) and I think have now covered all these leftovers. ------------- PR: https://git.openjdk.org/jdk/pull/12160 From jpai at openjdk.org Wed Jan 25 06:35:11 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 25 Jan 2023 06:35:11 GMT Subject: RFR: 8295944: Move the Http2TestServer and related classes into a package of its own [v3] In-Reply-To: References: Message-ID: > Can I please get a review of this change which addresses https://bugs.openjdk.org/browse/JDK-8295944? > > As noted in the issue, the HttpClient testing helper infrastructure code resides in a default (unnamed) packages within the test hierarchy. The commit in this PR moves those classes into a specific package. The tests have been updated to refer to them correctly with proper package name references. > Additionally as noted in the issue, the `@modules` declaration used in the httpclient tests, were all the same and were repeated in all these tests. The commit in this PR moves those module references into the `TEST.properties` to centralize such reference. Any test which needs additional modules can then use specific `@modules` declaration in the test definition. > > No functional changes have been done in this PR. > > tier1, tier2 and tier3 testing passed after these changes. Jaikiran Pai has updated the pull request incrementally with two additional commits since the last revision: - be consistent and use the full path of the library - remove left over content from the @modules that were removed ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12160/files - new: https://git.openjdk.org/jdk/pull/12160/files/97cbdc2e..ec0a6889 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12160&range=02 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12160&range=01-02 Stats: 40 lines in 22 files changed: 0 ins; 39 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/12160.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12160/head:pull/12160 PR: https://git.openjdk.org/jdk/pull/12160 From jpai at openjdk.org Wed Jan 25 07:02:07 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 25 Jan 2023 07:02:07 GMT Subject: RFR: 8295944: Move the Http2TestServer and related classes into a package of its own [v4] In-Reply-To: References: Message-ID: > Can I please get a review of this change which addresses https://bugs.openjdk.org/browse/JDK-8295944? > > As noted in the issue, the HttpClient testing helper infrastructure code resides in a default (unnamed) packages within the test hierarchy. The commit in this PR moves those classes into a specific package. The tests have been updated to refer to them correctly with proper package name references. > Additionally as noted in the issue, the `@modules` declaration used in the httpclient tests, were all the same and were repeated in all these tests. The commit in this PR moves those module references into the `TEST.properties` to centralize such reference. Any test which needs additional modules can then use specific `@modules` declaration in the test definition. > > No functional changes have been done in this PR. > > tier1, tier2 and tier3 testing passed after these changes. Jaikiran Pai has updated the pull request incrementally with one additional commit since the last revision: review suggestion - remove more common usages of @modules ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12160/files - new: https://git.openjdk.org/jdk/pull/12160/files/ec0a6889..7cee3fdc Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12160&range=03 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12160&range=02-03 Stats: 118 lines in 18 files changed: 2 ins; 116 del; 0 mod Patch: https://git.openjdk.org/jdk/pull/12160.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12160/head:pull/12160 PR: https://git.openjdk.org/jdk/pull/12160 From jpai at openjdk.org Wed Jan 25 07:08:05 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 25 Jan 2023 07:08:05 GMT Subject: RFR: 8295944: Move the Http2TestServer and related classes into a package of its own [v2] In-Reply-To: <-3bmvTZYKHK6p1ix0FyEKB3yxsoAqVLBvRfzHHWvPrg=.42cf0599-8d6a-4ca0-ad83-c2f46932db72@github.com> References: <5E30Z44CJ4M5z8pnLcd7b0E3GYwFjiCn9iyrghHFeNY=.da518784-c437-4d99-80e9-58c3e2ce20aa@github.com> <-3bmvTZYKHK6p1ix0FyEKB3yxsoAqVLBvRfzHHWvPrg=.42cf0599-8d6a-4ca0-ad83-c2f46932db72@github.com> Message-ID: On Tue, 24 Jan 2023 12:36:30 GMT, Daniel Fuchs wrote: > Also there are 9 classes that have kept their custom @modules clause because they want to access > > java.base/sun.net.www > java.base/sun.net > > I wonder if we should just add these two in TEST.properties - and then remove the @modules from these nine classes as well? I think that's reasonable. When I changed most of these tests to remove `@modules` from their test definition, my selection of "common" declarations missed out these two declarations. I've now updated the `TEST.properties` to include these and also updated the relevant tests to remove the `@modules` declaration. After this change, there remains few tests which use only a limited subset of the modules delcared in `TEST.properties`. I have left those tests as-is (for example `CancelledResponse.java`), since it didn't look necessary to remove those `@modules`. Let me know if you prefer otherwise and I'll update them as well. Local testing with the latest state of the PR passed. I've now triggered a broader testing with these changes. ------------- PR: https://git.openjdk.org/jdk/pull/12160 From dfuchs at openjdk.org Wed Jan 25 11:42:34 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Wed, 25 Jan 2023 11:42:34 GMT Subject: RFR: 8301004: httpclient: Add more debug to HttpResponseInputStream [v2] In-Reply-To: References: Message-ID: > The AsyncExecutorShutdown test has been observed failing (rarely) in our CI. The root cause seems to be an assertion error in HttpResponseInputStream. More debug traces could help with diagnosing how we reached this assertion. Daniel Fuchs has updated the pull request incrementally with two additional commits since the last revision: - Update src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java - Update src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12169/files - new: https://git.openjdk.org/jdk/pull/12169/files/885ae064..4387b1ab Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12169&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12169&range=00-01 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/12169.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12169/head:pull/12169 PR: https://git.openjdk.org/jdk/pull/12169 From dfuchs at openjdk.org Wed Jan 25 11:42:34 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Wed, 25 Jan 2023 11:42:34 GMT Subject: RFR: 8301004: httpclient: Add more debug to HttpResponseInputStream [v2] In-Reply-To: References: Message-ID: On Wed, 25 Jan 2023 11:38:27 GMT, Daniel Fuchs wrote: >> The AsyncExecutorShutdown test has been observed failing (rarely) in our CI. The root cause seems to be an assertion error in HttpResponseInputStream. More debug traces could help with diagnosing how we reached this assertion. > > Daniel Fuchs has updated the pull request incrementally with two additional commits since the last revision: > > - Update src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java > - Update src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java line 565: > 563: assert buffers.remainingCapacity() > 1 > 564: : "buffers capacity: " + buffers.remainingCapacity() > 565: + "closed: " + closed + "failed: " + failed; Suggestion: + " closed: " + closed + "failed: " + failed; src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java line 565: > 563: assert buffers.remainingCapacity() > 1 > 564: : "buffers capacity: " + buffers.remainingCapacity() > 565: + " closed: " + closed + "failed: " + failed; Suggestion: + " closed: " + closed + " failed: " + failed; ------------- PR: https://git.openjdk.org/jdk/pull/12169 From jpai at openjdk.org Wed Jan 25 11:45:14 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 25 Jan 2023 11:45:14 GMT Subject: RFR: 8301004: httpclient: Add more debug to HttpResponseInputStream [v2] In-Reply-To: References: Message-ID: On Wed, 25 Jan 2023 11:42:34 GMT, Daniel Fuchs wrote: >> The AsyncExecutorShutdown test has been observed failing (rarely) in our CI. The root cause seems to be an assertion error in HttpResponseInputStream. More debug traces could help with diagnosing how we reached this assertion. > > Daniel Fuchs has updated the pull request incrementally with two additional commits since the last revision: > > - Update src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java > - Update src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java Marked as reviewed by jpai (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12169 From dfuchs at openjdk.org Wed Jan 25 11:57:11 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Wed, 25 Jan 2023 11:57:11 GMT Subject: RFR: 8295944: Move the Http2TestServer and related classes into a package of its own [v4] In-Reply-To: References: Message-ID: On Wed, 25 Jan 2023 07:02:07 GMT, Jaikiran Pai wrote: >> Can I please get a review of this change which addresses https://bugs.openjdk.org/browse/JDK-8295944? >> >> As noted in the issue, the HttpClient testing helper infrastructure code resides in a default (unnamed) packages within the test hierarchy. The commit in this PR moves those classes into a specific package. The tests have been updated to refer to them correctly with proper package name references. >> Additionally as noted in the issue, the `@modules` declaration used in the httpclient tests, were all the same and were repeated in all these tests. The commit in this PR moves those module references into the `TEST.properties` to centralize such reference. Any test which needs additional modules can then use specific `@modules` declaration in the test definition. >> >> No functional changes have been done in this PR. >> >> tier1, tier2 and tier3 testing passed after these changes. > > Jaikiran Pai has updated the pull request incrementally with one additional commit since the last revision: > > review suggestion - remove more common usages of @modules Marked as reviewed by dfuchs (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12160 From dfuchs at openjdk.org Wed Jan 25 13:36:13 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Wed, 25 Jan 2023 13:36:13 GMT Subject: Integrated: 8301004: httpclient: Add more debug to HttpResponseInputStream In-Reply-To: References: Message-ID: On Tue, 24 Jan 2023 16:36:42 GMT, Daniel Fuchs wrote: > The AsyncExecutorShutdown test has been observed failing (rarely) in our CI. The root cause seems to be an assertion error in HttpResponseInputStream. More debug traces could help with diagnosing how we reached this assertion. This pull request has now been integrated. Changeset: c8ad6000 Author: Daniel Fuchs URL: https://git.openjdk.org/jdk/commit/c8ad6000646abd6e1faac396d901135c85c73cf5 Stats: 16 lines in 1 file changed: 14 ins; 0 del; 2 mod 8301004: httpclient: Add more debug to HttpResponseInputStream Reviewed-by: jpai ------------- PR: https://git.openjdk.org/jdk/pull/12169 From jpai at openjdk.org Wed Jan 25 13:38:07 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 25 Jan 2023 13:38:07 GMT Subject: RFR: 8295944: Move the Http2TestServer and related classes into a package of its own [v4] In-Reply-To: References: Message-ID: <2udthRsjyQYNAk8yh4u3dA3CIBwzkzU0AdkASEAkX7A=.07b9b0a0-0439-4af4-82be-a33b0322c54d@github.com> On Wed, 25 Jan 2023 07:02:07 GMT, Jaikiran Pai wrote: >> Can I please get a review of this change which addresses https://bugs.openjdk.org/browse/JDK-8295944? >> >> As noted in the issue, the HttpClient testing helper infrastructure code resides in a default (unnamed) packages within the test hierarchy. The commit in this PR moves those classes into a specific package. The tests have been updated to refer to them correctly with proper package name references. >> Additionally as noted in the issue, the `@modules` declaration used in the httpclient tests, were all the same and were repeated in all these tests. The commit in this PR moves those module references into the `TEST.properties` to centralize such reference. Any test which needs additional modules can then use specific `@modules` declaration in the test definition. >> >> No functional changes have been done in this PR. >> >> tier1, tier2 and tier3 testing passed after these changes. > > Jaikiran Pai has updated the pull request incrementally with one additional commit since the last revision: > > review suggestion - remove more common usages of @modules Thank you Daniel for the review. tier1, tier2, tier3 testing came back successful. ------------- PR: https://git.openjdk.org/jdk/pull/12160 From jpai at openjdk.org Wed Jan 25 13:41:16 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Wed, 25 Jan 2023 13:41:16 GMT Subject: Integrated: 8295944: Move the Http2TestServer and related classes into a package of its own In-Reply-To: References: Message-ID: <3hmqc0evuie5HRz2HhtSc3JG-9YQ08KY7KNqzsHPYMg=.f217f10c-875b-4a59-8ec7-178e04a3d382@github.com> On Tue, 24 Jan 2023 06:05:30 GMT, Jaikiran Pai wrote: > Can I please get a review of this change which addresses https://bugs.openjdk.org/browse/JDK-8295944? > > As noted in the issue, the HttpClient testing helper infrastructure code resides in a default (unnamed) packages within the test hierarchy. The commit in this PR moves those classes into a specific package. The tests have been updated to refer to them correctly with proper package name references. > Additionally as noted in the issue, the `@modules` declaration used in the httpclient tests, were all the same and were repeated in all these tests. The commit in this PR moves those module references into the `TEST.properties` to centralize such reference. Any test which needs additional modules can then use specific `@modules` declaration in the test definition. > > No functional changes have been done in this PR. > > tier1, tier2 and tier3 testing passed after these changes. This pull request has now been integrated. Changeset: 8a47429d Author: Jaikiran Pai URL: https://git.openjdk.org/jdk/commit/8a47429dc065ad7645a40fa2350d043ef4606d92 Stats: 1226 lines in 135 files changed: 276 ins; 467 del; 483 mod 8295944: Move the Http2TestServer and related classes into a package of its own Reviewed-by: dfuchs ------------- PR: https://git.openjdk.org/jdk/pull/12160 From duke at openjdk.org Wed Jan 25 14:53:19 2023 From: duke at openjdk.org (Darragh Clarke) Date: Wed, 25 Jan 2023 14:53:19 GMT Subject: RFR: 8300176: URLEncoder/URLDecoder static fields should be private static final [v2] In-Reply-To: References: Message-ID: <65TuRRBz7zkYabrxj1F9CWfz4qLmypmZwaMJwc89-Mc=.2c76653e-c60f-45d0-ab83-92867dc0e726@github.com> > Made the `static` fields `private static final`, updated the naming as well to reflect this. > > This meant I updated `URLDecoder` to set the `DEFAULT_ENCODING_NAME` itself since it had been previously getting it from `URLEncoder`. > > Since these fields are only referenced from inside the classes nothing else needed updated Darragh Clarke has updated the pull request incrementally with three additional commits since the last revision: - reduced bitset to 128 bits - formatting - implemented feedback from PR ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12122/files - new: https://git.openjdk.org/jdk/pull/12122/files/b08138d1..c276dce2 Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12122&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12122&range=00-01 Stats: 16 lines in 2 files changed: 0 ins; 10 del; 6 mod Patch: https://git.openjdk.org/jdk/pull/12122.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12122/head:pull/12122 PR: https://git.openjdk.org/jdk/pull/12122 From duke at openjdk.org Wed Jan 25 14:57:38 2023 From: duke at openjdk.org (Darragh Clarke) Date: Wed, 25 Jan 2023 14:57:38 GMT Subject: RFR: 8300176: URLEncoder/URLDecoder static fields should be private static final [v2] In-Reply-To: <65TuRRBz7zkYabrxj1F9CWfz4qLmypmZwaMJwc89-Mc=.2c76653e-c60f-45d0-ab83-92867dc0e726@github.com> References: <65TuRRBz7zkYabrxj1F9CWfz4qLmypmZwaMJwc89-Mc=.2c76653e-c60f-45d0-ab83-92867dc0e726@github.com> Message-ID: <9cBUCE1Dfiv2AWHgpmDpOuvKq3fbC9zcmJgzxFDRPyo=.a9b9e2f6-713a-4a2c-b927-3d6a5d6514b0@github.com> On Wed, 25 Jan 2023 14:53:19 GMT, Darragh Clarke wrote: >> Made the `static` fields `private static final`, updated the naming as well to reflect this. >> >> This meant I updated `URLDecoder` to set the `DEFAULT_ENCODING_NAME` itself since it had been previously getting it from `URLEncoder`. >> >> Since these fields are only referenced from inside the classes nothing else needed updated > > Darragh Clarke has updated the pull request incrementally with three additional commits since the last revision: > > - reduced bitset to 128 bits > - formatting > - implemented feedback from PR I pushed changes there based on the comments, and to touch on some points brought up Personally I'd prefer to keep `DEFAULT_ENCODING_NAME` just for readability, though I'm not incredibly pushed on that if folk think it'd be better to just replace its usages with a direct call. And as for testing, I ran some benchmarks on my local machine that did show a speed up after the changes, but this was my first time using JMH so I was wondering if you have any pointers @cl4es as to what settings/how many iterations should I run before I can be confident in any results it gives? ------------- PR: https://git.openjdk.org/jdk/pull/12122 From michaelm at openjdk.org Wed Jan 25 17:12:16 2023 From: michaelm at openjdk.org (Michael McMahon) Date: Wed, 25 Jan 2023 17:12:16 GMT Subject: RFR: 8300176: URLEncoder/URLDecoder static fields should be private static final [v2] In-Reply-To: <65TuRRBz7zkYabrxj1F9CWfz4qLmypmZwaMJwc89-Mc=.2c76653e-c60f-45d0-ab83-92867dc0e726@github.com> References: <65TuRRBz7zkYabrxj1F9CWfz4qLmypmZwaMJwc89-Mc=.2c76653e-c60f-45d0-ab83-92867dc0e726@github.com> Message-ID: <8L86S6zj9jp6-FdLp59CIePezoCSM7t4Ov47xOleccU=.95077508-471c-4528-a98d-1966ece1f3a8@github.com> On Wed, 25 Jan 2023 14:53:19 GMT, Darragh Clarke wrote: >> Made the `static` fields `private static final`, updated the naming as well to reflect this. >> >> This meant I updated `URLDecoder` to set the `DEFAULT_ENCODING_NAME` itself since it had been previously getting it from `URLEncoder`. >> >> Since these fields are only referenced from inside the classes nothing else needed updated > > Darragh Clarke has updated the pull request incrementally with three additional commits since the last revision: > > - reduced bitset to 128 bits > - formatting > - implemented feedback from PR Looks fine to me ------------- Marked as reviewed by michaelm (Reviewer). PR: https://git.openjdk.org/jdk/pull/12122 From michaelm at openjdk.org Wed Jan 25 17:16:43 2023 From: michaelm at openjdk.org (Michael McMahon) Date: Wed, 25 Jan 2023 17:16:43 GMT Subject: RFR: 8287134: HttpURLConnection chunked streaming mode doesn't enforce specified size [v2] In-Reply-To: References: Message-ID: <_w-zXVFB5e_8L5PGit90yrKiJ0Q-FjmUBys-Mq74hZM=.7bcd18d9-5c50-4bda-9735-043a506f16d6@github.com> On Mon, 23 Jan 2023 12:29:16 GMT, Conor Cleary wrote: >> ### **Description** >> When using `HttpURLConnection::setChunkedStreamingMode()`, the current documentation does not make it clear that the `chunklen` parameter refers to the amount of bytes sent on the wire per HTTP/1.1 chunk and _not_ the payload length per chunk. The `chunklen` parameter takes into account the bytes used for the chunk size header, two CRLF characters and the possible payload length inclusively. >> >> ### **Summary of Changes & Justification** >> The API text has been updated to reflect the actual behavior of the method as described above to avoid a similar bug being submitted in the future and to make it clear what the `chunklen` parameter specifies. >> >> This change will require a csr. > > Conor Cleary has updated the pull request incrementally with one additional commit since the last revision: > > 8287134: Shortened text and corrected typo Looks fine. ------------- Marked as reviewed by michaelm (Reviewer). PR: https://git.openjdk.org/jdk/pull/12137 From stsypanov at openjdk.org Wed Jan 25 18:12:48 2023 From: stsypanov at openjdk.org (Sergey Tsypanov) Date: Wed, 25 Jan 2023 18:12:48 GMT Subject: RFR: 8300176: URLEncoder/URLDecoder static fields should be private static final [v2] In-Reply-To: <65TuRRBz7zkYabrxj1F9CWfz4qLmypmZwaMJwc89-Mc=.2c76653e-c60f-45d0-ab83-92867dc0e726@github.com> References: <65TuRRBz7zkYabrxj1F9CWfz4qLmypmZwaMJwc89-Mc=.2c76653e-c60f-45d0-ab83-92867dc0e726@github.com> Message-ID: On Wed, 25 Jan 2023 14:53:19 GMT, Darragh Clarke wrote: >> Made the `static` fields `private static final`, updated the naming as well to reflect this. >> >> This meant I updated `URLDecoder` to set the `DEFAULT_ENCODING_NAME` itself since it had been previously getting it from `URLEncoder`. >> >> Since these fields are only referenced from inside the classes nothing else needed updated > > Darragh Clarke has updated the pull request incrementally with three additional commits since the last revision: > > - reduced bitset to 128 bits > - formatting > - implemented feedback from PR Marked as reviewed by stsypanov (Author). ------------- PR: https://git.openjdk.org/jdk/pull/12122 From ccleary at openjdk.org Thu Jan 26 08:38:43 2023 From: ccleary at openjdk.org (Conor Cleary) Date: Thu, 26 Jan 2023 08:38:43 GMT Subject: Integrated: 8287134: HttpURLConnection chunked streaming mode doesn't enforce specified size In-Reply-To: References: Message-ID: On Mon, 23 Jan 2023 09:04:58 GMT, Conor Cleary wrote: > ### **Description** > When using `HttpURLConnection::setChunkedStreamingMode()`, the current documentation does not make it clear that the `chunklen` parameter refers to the amount of bytes sent on the wire per HTTP/1.1 chunk and _not_ the payload length per chunk. The `chunklen` parameter takes into account the bytes used for the chunk size header, two CRLF characters and the possible payload length inclusively. > > ### **Summary of Changes & Justification** > The API text has been updated to reflect the actual behavior of the method as described above to avoid a similar bug being submitted in the future and to make it clear what the `chunklen` parameter specifies. > > This change will require a csr. This pull request has now been integrated. Changeset: 48152ef6 Author: Conor Cleary URL: https://git.openjdk.org/jdk/commit/48152ef66f2466f8c80499325a716de0cb45d8ef Stats: 5 lines in 1 file changed: 2 ins; 0 del; 3 mod 8287134: HttpURLConnection chunked streaming mode doesn't enforce specified size Reviewed-by: dfuchs, michaelm ------------- PR: https://git.openjdk.org/jdk/pull/12137 From dfuchs at openjdk.org Thu Jan 26 10:19:25 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Thu, 26 Jan 2023 10:19:25 GMT Subject: RFR: 8300176: URLEncoder/URLDecoder static fields should be private static final [v2] In-Reply-To: <65TuRRBz7zkYabrxj1F9CWfz4qLmypmZwaMJwc89-Mc=.2c76653e-c60f-45d0-ab83-92867dc0e726@github.com> References: <65TuRRBz7zkYabrxj1F9CWfz4qLmypmZwaMJwc89-Mc=.2c76653e-c60f-45d0-ab83-92867dc0e726@github.com> Message-ID: On Wed, 25 Jan 2023 14:53:19 GMT, Darragh Clarke wrote: >> Made the `static` fields `private static final`, updated the naming as well to reflect this. >> >> This meant I updated `URLDecoder` to set the `DEFAULT_ENCODING_NAME` itself since it had been previously getting it from `URLEncoder`. >> >> Since these fields are only referenced from inside the classes nothing else needed updated > > Darragh Clarke has updated the pull request incrementally with three additional commits since the last revision: > > - reduced bitset to 128 bits > - formatting > - implemented feedback from PR LGTM ------------- Marked as reviewed by dfuchs (Reviewer). PR: https://git.openjdk.org/jdk/pull/12122 From redestad at openjdk.org Thu Jan 26 11:28:19 2023 From: redestad at openjdk.org (Claes Redestad) Date: Thu, 26 Jan 2023 11:28:19 GMT Subject: RFR: 8300176: URLEncoder/URLDecoder static fields should be private static final [v2] In-Reply-To: <9cBUCE1Dfiv2AWHgpmDpOuvKq3fbC9zcmJgzxFDRPyo=.a9b9e2f6-713a-4a2c-b927-3d6a5d6514b0@github.com> References: <65TuRRBz7zkYabrxj1F9CWfz4qLmypmZwaMJwc89-Mc=.2c76653e-c60f-45d0-ab83-92867dc0e726@github.com> <9cBUCE1Dfiv2AWHgpmDpOuvKq3fbC9zcmJgzxFDRPyo=.a9b9e2f6-713a-4a2c-b927-3d6a5d6514b0@github.com> Message-ID: On Wed, 25 Jan 2023 14:54:55 GMT, Darragh Clarke wrote: > And as for testing, I ran some benchmarks on my local machine that did show a speed up after the changes, but this was my first time using JMH so I was wondering if you have any pointers @cl4es as to what settings/how many iterations should I run before I can be confident in any results it gives? As a rule of thumb if you get the approximate same results when running the same benchmark back to back and the difference between your baseline and test results is decidedly larger than the sum of the errors then you can have a reasonably high confidence in the results. If errors are too high for comfort (or effect too small) you should first consider if your benchmarking system can be made quieter (e.g. turning off browsers, slack, IDEs, turn off hyperthreading, turbo boost, apply firmware updates, put the box in a freezer, don't move, don't make a sound...!), then if you're still not getting comfortably consistent results you can increase the amount of forks, warmup and measurement iterations you're running with. ------------- PR: https://git.openjdk.org/jdk/pull/12122 From duke at openjdk.org Thu Jan 26 14:35:18 2023 From: duke at openjdk.org (Darragh Clarke) Date: Thu, 26 Jan 2023 14:35:18 GMT Subject: RFR: 8300176: URLEncoder/URLDecoder static fields should be private static final [v2] In-Reply-To: References: <65TuRRBz7zkYabrxj1F9CWfz4qLmypmZwaMJwc89-Mc=.2c76653e-c60f-45d0-ab83-92867dc0e726@github.com> <9cBUCE1Dfiv2AWHgpmDpOuvKq3fbC9zcmJgzxFDRPyo=.a9b9e2f6-713a-4a2c-b927-3d6a5d6514b0@github.com> Message-ID: On Thu, 26 Jan 2023 11:25:29 GMT, Claes Redestad wrote: > As a rule of thumb if you get the approximate same results when running the same benchmark back to back and the difference between your baseline and test results is decidedly larger than the sum of the errors then you can have a reasonably high confidence in the results. > > If errors are too high for comfort (or effect too small) you should first consider if your benchmarking system can be made quieter (e.g. turning off browsers, slack, IDEs, turn off hyperthreading, turbo boost, apply firmware updates, put the box in a freezer, don't move, don't make a sound...!), then if you're still not getting comfortably consistent results you can increase the amount of forks, warmup and measurement iterations you're running with. So I did some runs yesterday and then a few more today and it seems like on my machine the average time dropped around 15% for the `EncodeDecode` test, It seemed pretty consistent with that though I'm sure I was far from thorough ------------- PR: https://git.openjdk.org/jdk/pull/12122 From dfuchs at openjdk.org Thu Jan 26 19:45:58 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Thu, 26 Jan 2023 19:45:58 GMT Subject: RFR: 8299325: java/net/httpclient/CancelRequestTest.java fails "test CancelRequestTest.testGetSendAsync("https://localhost:46509/https1/x/same/interrupt", true, true)" Message-ID: The CancelRequestTest has been observed failing (rare and intermittent, but at least twice) in our CI. This fix increases the timeout waiting for resources to be released after cancelling the request, and add more diagnosis to the test code. ------------- Commit messages: - 8299325 Changes: https://git.openjdk.org/jdk/pull/12233/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12233&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8299325 Stats: 36 lines in 1 file changed: 20 ins; 1 del; 15 mod Patch: https://git.openjdk.org/jdk/pull/12233.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12233/head:pull/12233 PR: https://git.openjdk.org/jdk/pull/12233 From jpai at openjdk.org Fri Jan 27 10:52:17 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Fri, 27 Jan 2023 10:52:17 GMT Subject: RFR: 8300176: URLEncoder/URLDecoder static fields should be private static final [v2] In-Reply-To: <65TuRRBz7zkYabrxj1F9CWfz4qLmypmZwaMJwc89-Mc=.2c76653e-c60f-45d0-ab83-92867dc0e726@github.com> References: <65TuRRBz7zkYabrxj1F9CWfz4qLmypmZwaMJwc89-Mc=.2c76653e-c60f-45d0-ab83-92867dc0e726@github.com> Message-ID: On Wed, 25 Jan 2023 14:53:19 GMT, Darragh Clarke wrote: >> Made the `static` fields `private static final`, updated the naming as well to reflect this. >> >> This meant I updated `URLDecoder` to set the `DEFAULT_ENCODING_NAME` itself since it had been previously getting it from `URLEncoder`. >> >> Since these fields are only referenced from inside the classes nothing else needed updated > > Darragh Clarke has updated the pull request incrementally with three additional commits since the last revision: > > - reduced bitset to 128 bits > - formatting > - implemented feedback from PR Marked as reviewed by jpai (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12122 From duke at openjdk.org Fri Jan 27 10:55:26 2023 From: duke at openjdk.org (Darragh Clarke) Date: Fri, 27 Jan 2023 10:55:26 GMT Subject: Integrated: 8300176: URLEncoder/URLDecoder static fields should be private static final In-Reply-To: References: Message-ID: On Fri, 20 Jan 2023 17:41:55 GMT, Darragh Clarke wrote: > Made the `static` fields `private static final`, updated the naming as well to reflect this. > > This meant I updated `URLDecoder` to set the `DEFAULT_ENCODING_NAME` itself since it had been previously getting it from `URLEncoder`. > > Since these fields are only referenced from inside the classes nothing else needed updated This pull request has now been integrated. Changeset: d7aa87fd Author: Darragh Clarke Committer: Jaikiran Pai URL: https://git.openjdk.org/jdk/commit/d7aa87fdbdc0f3c5bc6c3a7a9c1b57f25fdaebd1 Stats: 31 lines in 2 files changed: 2 ins; 6 del; 23 mod 8300176: URLEncoder/URLDecoder static fields should be private static final Reviewed-by: redestad, michaelm, stsypanov, dfuchs, jpai ------------- PR: https://git.openjdk.org/jdk/pull/12122 From dfuchs at openjdk.org Fri Jan 27 18:24:01 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Fri, 27 Jan 2023 18:24:01 GMT Subject: RFR: 8301255: Http2Connection may send too many GOAWAY frames Message-ID: The following behavior was observed in a test log: DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) sending frame: GOAWAY: length=25, streamid=0, flags=0 Error: Not an error Debugdata: Requested by user DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) added 34 bytes to the write queue DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) signalling the publisher of the write queue DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) sending frame: GOAWAY: length=25, streamid=0, flags=0 Error: Not an error Debugdata: Requested by user DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) added 34 bytes to the write queue DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) signalling the publisher of the write queue DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped etc... What happens here is that attempting to send a GOAWAY frame after some error was detected might cause an error which triggers an attempt to shutdown the connection again and cause a new GOAWAY frame to be sent. This seems to happen when trying to shutdown the client and close HTTP/2 TLS connections gracefully. The fix changes the simple 'closed' boolean into a bit mask that can combined the several closed states of the connection: `Http2Connection::shutdown` has been called, SHUTDOWN is requested (previously was closed=true), a GOAWAY frame has been sent (the connection is half closed local), a GOAWAY connection has been received (the connection is half closed remote). If the connection is already half-closed locally - a GOAWAY frame has been sent already and there's no need to send a new one. This will also better help diagnose the actual state of the connection at the time `Http2Connection::shutdown` is called. ------------- Commit messages: - 8301255 Changes: https://git.openjdk.org/jdk/pull/12263/files Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=12263&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8301255 Stats: 106 lines in 3 files changed: 73 ins; 5 del; 28 mod Patch: https://git.openjdk.org/jdk/pull/12263.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12263/head:pull/12263 PR: https://git.openjdk.org/jdk/pull/12263 From duke at openjdk.org Fri Jan 27 18:43:34 2023 From: duke at openjdk.org (duke) Date: Fri, 27 Jan 2023 18:43:34 GMT Subject: Withdrawn: 8296546: Add @spec tags to API In-Reply-To: <5uS_XWg0xRt6Rp20wY65rAmNRcDrp5XN_74k1aQ_4jk=.9f458354-9bca-473e-b60e-e520fa90724b@github.com> References: <5uS_XWg0xRt6Rp20wY65rAmNRcDrp5XN_74k1aQ_4jk=.9f458354-9bca-473e-b60e-e520fa90724b@github.com> Message-ID: On Thu, 10 Nov 2022 01:10:13 GMT, Jonathan Gibbons wrote: > Please review a "somewhat automated" change to insert `@spec` tags into doc comments, as appropriate, to leverage the recent new javadoc feature to generate a new page listing the references to all external specifications listed in the `@spec` tags. > > "Somewhat automated" means that I wrote and used a temporary utility to scan doc comments looking for HTML links to selected sites, such as `ietf.org`, `unicode.org`, `w3.org`. These links may be in the main description of a doc comment, or in `@see` tags. For each link, the URL is examined, and "normalized", and inserted into the doc comment with a new `@spec` tag, giving the link and tile for the spec. > > "Normalized" means... > * Use `https:` where possible (includes pretty much all cases) > * Use a single consistent host name for all URLs coming from the same spec site (i.e. don't use different aliases for the same site) > * Point to the root page of a multi-page spec > * Use a consistent form of the spec, preferring HTML over plain text where both are available (this mostly applies to IETF specs) > > In addition, a "standard" title is determined for all specs, determined either from the content of the (main) spec page or from site index pages. > > The net effect is (or should be) that **all** the changes are to just **add** new `@spec` tags, based on the links found in each doc comment. There should be no other changes to the doc comments, or to the implementation of any classes and interfaces. > > That being said, the utility I wrote does have additional abilities, to update the links that it finds (e.g. changing to use `https:` etc,) but those features are _not_ being used here, but could be used in followup PRs if component teams so desired. I did notice while working on this overall feature that many of our links do point to "outdated" pages, some with eye-catching notices declaring that the spec has been superseded. Determining how, when and where to update such links is beyond the scope of this PR. > > Going forward, it is to be hoped that component teams will maintain the underlying links, and the URLs in `@spec` tags, such that if references to external specifications are updated, this will include updating the `@spec` tags. > > To see the effect of all these new `@spec` tags, see http://cr.openjdk.java.net/~jjg/8296546/api.00/ > > In particular, see the new [External Specifications](http://cr.openjdk.java.net/~jjg/8296546/api.00/external-specs.html) page, which you can also find via the new link near the top of the [Index](http://cr.openjdk.java.net/~jjg/8296546/api.00/index-files/index-1.html) pages. This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.org/jdk/pull/11073 From jpai at openjdk.org Mon Jan 30 08:52:16 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Mon, 30 Jan 2023 08:52:16 GMT Subject: RFR: 8301255: Http2Connection may send too many GOAWAY frames In-Reply-To: References: Message-ID: On Fri, 27 Jan 2023 18:16:20 GMT, Daniel Fuchs wrote: > The following behavior was observed in a test log: > > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) sending frame: GOAWAY: length=25, streamid=0, flags=0 Error: Not an error Debugdata: Requested by user > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) added 34 bytes to the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) signalling the publisher of the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) sending frame: GOAWAY: length=25, streamid=0, flags=0 Error: Not an error Debugdata: Requested by user > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) added 34 bytes to the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) signalling the publisher of the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped > etc... > > What happens here is that attempting to send a GOAWAY frame after some error was detected might cause an error which triggers an attempt to shutdown the connection again and cause a new GOAWAY frame to be sent. This seems to happen when trying to shutdown the client and close HTTP/2 TLS connections gracefully. > > The fix changes the simple 'closed' boolean into a bit mask that can combined the several closed states of the connection: `Http2Connection::shutdown` has been called, SHUTDOWN is requested (previously was closed=true), a GOAWAY frame has been sent (the connection is half closed local), a GOAWAY connection has been received (the connection is half closed remote). > > If the connection is already half-closed locally - a GOAWAY frame has been sent already and there's no need to send a new one. > > This will also better help diagnose the actual state of the connection at the time `Http2Connection::shutdown` is called. src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java line 205: > 203: STOPPED = new EOFException("HTTP/2 client stopped"); > 204: STOPPED.setStackTrace(new StackTraceElement[0]); > 205: synchronized (this) {stopping = true;} Hello Daniel, the other places where these `stopping` and the `STOPPED` get used appears to be when a connection is offered back to the HttpClient pool. So moving this setting of `stopping` appears OK to me. ------------- PR: https://git.openjdk.org/jdk/pull/12263 From jpai at openjdk.org Mon Jan 30 09:14:17 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Mon, 30 Jan 2023 09:14:17 GMT Subject: RFR: 8301255: Http2Connection may send too many GOAWAY frames In-Reply-To: References: Message-ID: On Fri, 27 Jan 2023 18:16:20 GMT, Daniel Fuchs wrote: > The following behavior was observed in a test log: > > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) sending frame: GOAWAY: length=25, streamid=0, flags=0 Error: Not an error Debugdata: Requested by user > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) added 34 bytes to the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) signalling the publisher of the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) sending frame: GOAWAY: length=25, streamid=0, flags=0 Error: Not an error Debugdata: Requested by user > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) added 34 bytes to the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) signalling the publisher of the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped > etc... > > What happens here is that attempting to send a GOAWAY frame after some error was detected might cause an error which triggers an attempt to shutdown the connection again and cause a new GOAWAY frame to be sent. This seems to happen when trying to shutdown the client and close HTTP/2 TLS connections gracefully. > > The fix changes the simple 'closed' boolean into a bit mask that can combined the several closed states of the connection: `Http2Connection::shutdown` has been called, SHUTDOWN is requested (previously was closed=true), a GOAWAY frame has been sent (the connection is half closed local), a GOAWAY connection has been received (the connection is half closed remote). > > If the connection is already half-closed locally - a GOAWAY frame has been sent already and there's no need to send a new one. > > This will also better help diagnose the actual state of the connection at the time `Http2Connection::shutdown` is called. Overall, these changes look good to me and the introduction of the different states is going to help this part of the connection management code. I just have a question about the `close()` method (unrelated to this PR), which I've asked inline. src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java line 674: > 672: // TODO: set last stream. For now zero ok. > 673: sendFrame(f); > 674: } Unrelated to this PR, even before these changes, looking at this implementation of `close()` it's odd that this method isn't setting `closed` flag to `true` and is neither calling `shutdown` to do the additional things that the `shutdown` does. I haven't yet paid a closer attention to the callers of this method to be sure if that's OK. I'm guessing it is OK, otherwise I think we would have seen issues by now. Maybe this `close()` method should be renamed to `sendGoAway` if that's what it is meant for? ------------- PR: https://git.openjdk.org/jdk/pull/12263 From jpai at openjdk.org Mon Jan 30 09:25:23 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Mon, 30 Jan 2023 09:25:23 GMT Subject: RFR: 8299325: java/net/httpclient/CancelRequestTest.java fails "test CancelRequestTest.testGetSendAsync("https://localhost:46509/https1/x/same/interrupt", true, true)" In-Reply-To: References: Message-ID: <2xL31gdQ4D1WcrUbaQnEcHW_8VEN1mchqMd67RcTQ7k=.5bd6244e-3075-4e8a-bd55-55acc305edf3@github.com> On Thu, 26 Jan 2023 19:37:52 GMT, Daniel Fuchs wrote: > The CancelRequestTest has been observed failing (rare and intermittent, but at least twice) in our CI. > This fix increases the timeout waiting for resources to be released after cancelling the request, and add more diagnosis to the test code. Marked as reviewed by jpai (Reviewer). test/jdk/java/net/httpclient/CancelRequestTest.java line 369: > 367: } > 368: } > 369: if (!IOException.class.isAssignableFrom(cause.getClass())) { Just to make it a bit easier to read, do you think we could change this to: if (!IOException.class.isInstance(cause)) { ... ------------- PR: https://git.openjdk.org/jdk/pull/12233 From dfuchs at openjdk.org Mon Jan 30 11:04:19 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Mon, 30 Jan 2023 11:04:19 GMT Subject: RFR: 8301255: Http2Connection may send too many GOAWAY frames In-Reply-To: References: Message-ID: On Mon, 30 Jan 2023 09:09:50 GMT, Jaikiran Pai wrote: >> The following behavior was observed in a test log: >> >> DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped >> DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams >> DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams >> DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) sending frame: GOAWAY: length=25, streamid=0, flags=0 Error: Not an error Debugdata: Requested by user >> DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) added 34 bytes to the write queue >> DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) signalling the publisher of the write queue >> DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped >> DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams >> DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams >> DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) sending frame: GOAWAY: length=25, streamid=0, flags=0 Error: Not an error Debugdata: Requested by user >> DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) added 34 bytes to the write queue >> DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) signalling the publisher of the write queue >> DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped >> etc... >> >> What happens here is that attempting to send a GOAWAY frame after some error was detected might cause an error which triggers an attempt to shutdown the connection again and cause a new GOAWAY frame to be sent. This seems to happen when trying to shutdown the client and close HTTP/2 TLS connections gracefully. >> >> The fix changes the simple 'closed' boolean into a bit mask that can combined the several closed states of the connection: `Http2Connection::shutdown` has been called, SHUTDOWN is requested (previously was closed=true), a GOAWAY frame has been sent (the connection is half closed local), a GOAWAY connection has been received (the connection is half closed remote). >> >> If the connection is already half-closed locally - a GOAWAY frame has been sent already and there's no need to send a new one. >> >> This will also better help diagnose the actual state of the connection at the time `Http2Connection::shutdown` is called. > > src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java line 674: > >> 672: // TODO: set last stream. For now zero ok. >> 673: sendFrame(f); >> 674: } > > Unrelated to this PR, even before these changes, looking at this implementation of `close()` it's odd that this method isn't setting `closed` flag to `true` and is neither calling `shutdown` to do the additional things that the `shutdown` does. I haven't yet paid a closer attention to the callers of this method to be sure if that's OK. I'm guessing it is OK, otherwise I think we would have seen issues by now. > Maybe this `close()` method should be renamed to `sendGoAway` if that's what it is meant for? close() is supposed to be a graceful shutdown - sending GOAWAY with no error, and that's why it doesn't close the connection immediately. You are right however that the naming sounds a bit strange. I should probably log another issue to revisit how GOAWAY is handled by the HttpClient in the HTTP/2 stack. ------------- PR: https://git.openjdk.org/jdk/pull/12263 From jpai at openjdk.org Mon Jan 30 11:11:16 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Mon, 30 Jan 2023 11:11:16 GMT Subject: RFR: 8301255: Http2Connection may send too many GOAWAY frames In-Reply-To: References: Message-ID: On Fri, 27 Jan 2023 18:16:20 GMT, Daniel Fuchs wrote: > The following behavior was observed in a test log: > > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) sending frame: GOAWAY: length=25, streamid=0, flags=0 Error: Not an error Debugdata: Requested by user > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) added 34 bytes to the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) signalling the publisher of the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) sending frame: GOAWAY: length=25, streamid=0, flags=0 Error: Not an error Debugdata: Requested by user > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) added 34 bytes to the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) signalling the publisher of the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped > etc... > > What happens here is that attempting to send a GOAWAY frame after some error was detected might cause an error which triggers an attempt to shutdown the connection again and cause a new GOAWAY frame to be sent. This seems to happen when trying to shutdown the client and close HTTP/2 TLS connections gracefully. > > The fix changes the simple 'closed' boolean into a bit mask that can combined the several closed states of the connection: `Http2Connection::shutdown` has been called, SHUTDOWN is requested (previously was closed=true), a GOAWAY frame has been sent (the connection is half closed local), a GOAWAY connection has been received (the connection is half closed remote). > > If the connection is already half-closed locally - a GOAWAY frame has been sent already and there's no need to send a new one. > > This will also better help diagnose the actual state of the connection at the time `Http2Connection::shutdown` is called. Marked as reviewed by jpai (Reviewer). ------------- PR: https://git.openjdk.org/jdk/pull/12263 From jpai at openjdk.org Mon Jan 30 11:11:18 2023 From: jpai at openjdk.org (Jaikiran Pai) Date: Mon, 30 Jan 2023 11:11:18 GMT Subject: RFR: 8301255: Http2Connection may send too many GOAWAY frames In-Reply-To: References: Message-ID: On Mon, 30 Jan 2023 11:01:12 GMT, Daniel Fuchs wrote: > I should probably log another issue to revisit how GOAWAY is handled by the HttpClient in the HTTP/2 stack. That sounds fine to me. ------------- PR: https://git.openjdk.org/jdk/pull/12263 From dfuchs at openjdk.org Mon Jan 30 14:39:24 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Mon, 30 Jan 2023 14:39:24 GMT Subject: Integrated: 8301255: Http2Connection may send too many GOAWAY frames In-Reply-To: References: Message-ID: On Fri, 27 Jan 2023 18:16:20 GMT, Daniel Fuchs wrote: > The following behavior was observed in a test log: > > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) sending frame: GOAWAY: length=25, streamid=0, flags=0 Error: Not an error Debugdata: Requested by user > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) added 34 bytes to the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) signalling the publisher of the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Close all streams > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) sending frame: GOAWAY: length=25, streamid=0, flags=0 Error: Not an error Debugdata: Requested by user > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) added 34 bytes to the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] AsyncSSLConnection(SSLTube(SocketTube(2))) signalling the publisher of the write queue > DEBUG: [HttpClient-2-SelectorManager] [2s 716ms] Http2Connection(SSLTube(SocketTube(2))) Shutting down h2c (closed=true): java.io.EOFException: HTTP/2 client stopped > etc... > > What happens here is that attempting to send a GOAWAY frame after some error was detected might cause an error which triggers an attempt to shutdown the connection again and cause a new GOAWAY frame to be sent. This seems to happen when trying to shutdown the client and close HTTP/2 TLS connections gracefully. > > The fix changes the simple 'closed' boolean into a bit mask that can combined the several closed states of the connection: `Http2Connection::shutdown` has been called, SHUTDOWN is requested (previously was closed=true), a GOAWAY frame has been sent (the connection is half closed local), a GOAWAY connection has been received (the connection is half closed remote). > > If the connection is already half-closed locally - a GOAWAY frame has been sent already and there's no need to send a new one. > > This will also better help diagnose the actual state of the connection at the time `Http2Connection::shutdown` is called. This pull request has now been integrated. Changeset: 041a12e6 Author: Daniel Fuchs URL: https://git.openjdk.org/jdk/commit/041a12e65530b5832b4a500180c97a2a60e0dc51 Stats: 106 lines in 3 files changed: 73 ins; 5 del; 28 mod 8301255: Http2Connection may send too many GOAWAY frames Reviewed-by: jpai ------------- PR: https://git.openjdk.org/jdk/pull/12263 From dfuchs at openjdk.org Mon Jan 30 14:45:58 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Mon, 30 Jan 2023 14:45:58 GMT Subject: RFR: 8299325: java/net/httpclient/CancelRequestTest.java fails "test CancelRequestTest.testGetSendAsync("https://localhost:46509/https1/x/same/interrupt", true, true)" [v2] In-Reply-To: References: Message-ID: <_RTUE97U_BParm6rnqTwB9fcBbSDZbMl6VzguOAz8u0=.8ba45f82-0b57-4872-becf-affc55b38788@github.com> > The CancelRequestTest has been observed failing (rare and intermittent, but at least twice) in our CI. > This fix increases the timeout waiting for resources to be released after cancelling the request, and add more diagnosis to the test code. Daniel Fuchs has updated the pull request incrementally with one additional commit since the last revision: Update test/jdk/java/net/httpclient/CancelRequestTest.java ------------- Changes: - all: https://git.openjdk.org/jdk/pull/12233/files - new: https://git.openjdk.org/jdk/pull/12233/files/9847f7bc..2196dd9b Webrevs: - full: https://webrevs.openjdk.org/?repo=jdk&pr=12233&range=01 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=12233&range=00-01 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jdk/pull/12233.diff Fetch: git fetch https://git.openjdk.org/jdk pull/12233/head:pull/12233 PR: https://git.openjdk.org/jdk/pull/12233 From dfuchs at openjdk.org Mon Jan 30 14:45:58 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Mon, 30 Jan 2023 14:45:58 GMT Subject: RFR: 8299325: java/net/httpclient/CancelRequestTest.java fails "test CancelRequestTest.testGetSendAsync("https://localhost:46509/https1/x/same/interrupt", true, true)" [v2] In-Reply-To: <_RTUE97U_BParm6rnqTwB9fcBbSDZbMl6VzguOAz8u0=.8ba45f82-0b57-4872-becf-affc55b38788@github.com> References: <_RTUE97U_BParm6rnqTwB9fcBbSDZbMl6VzguOAz8u0=.8ba45f82-0b57-4872-becf-affc55b38788@github.com> Message-ID: On Mon, 30 Jan 2023 14:42:20 GMT, Daniel Fuchs wrote: >> The CancelRequestTest has been observed failing (rare and intermittent, but at least twice) in our CI. >> This fix increases the timeout waiting for resources to be released after cancelling the request, and add more diagnosis to the test code. > > Daniel Fuchs has updated the pull request incrementally with one additional commit since the last revision: > > Update test/jdk/java/net/httpclient/CancelRequestTest.java test/jdk/java/net/httpclient/CancelRequestTest.java line 369: > 367: } > 368: } > 369: if (!IOException.class.isAssignableFrom(cause.getClass())) { Thanks Jaikiran. Good suggestion! Suggestion: if (!IOException.class.isInstance(cause)) { ------------- PR: https://git.openjdk.org/jdk/pull/12233 From dfuchs at openjdk.org Mon Jan 30 14:45:58 2023 From: dfuchs at openjdk.org (Daniel Fuchs) Date: Mon, 30 Jan 2023 14:45:58 GMT Subject: Integrated: 8299325: java/net/httpclient/CancelRequestTest.java fails "test CancelRequestTest.testGetSendAsync("https://localhost:46509/https1/x/same/interrupt", true, true)" In-Reply-To: References: Message-ID: On Thu, 26 Jan 2023 19:37:52 GMT, Daniel Fuchs wrote: > The CancelRequestTest has been observed failing (rare and intermittent, but at least twice) in our CI. > This fix increases the timeout waiting for resources to be released after cancelling the request, and add more diagnosis to the test code. This pull request has now been integrated. Changeset: a74ebd04 Author: Daniel Fuchs URL: https://git.openjdk.org/jdk/commit/a74ebd048ae569296619c112c23169c46b571863 Stats: 36 lines in 1 file changed: 20 ins; 1 del; 15 mod 8299325: java/net/httpclient/CancelRequestTest.java fails "test CancelRequestTest.testGetSendAsync("https://localhost:46509/https1/x/same/interrupt", true, true)" Reviewed-by: jpai ------------- PR: https://git.openjdk.org/jdk/pull/12233