From a80ed238128f5196d705abce17fb7e26ee724f93 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Thu, 9 Jan 2025 03:33:21 +0000 Subject: [PATCH 01/25] 8347296: WinInstallerUiTest fails in local test runs if the path to test work directory is longer that regular Reviewed-by: almatvee --- test/jdk/tools/jpackage/windows/WinInstallerUiTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java b/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java index c6489ab68cf..7dcf025a506 100644 --- a/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java +++ b/test/jdk/tools/jpackage/windows/WinInstallerUiTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -122,13 +122,13 @@ private void setPackageName(JPackageCommand cmd) { StringBuilder sb = new StringBuilder(cmd.name()); sb.append("With"); if (withDirChooser) { - sb.append("DirChooser"); + sb.append("Dc"); // DirChooser } if (withShortcutPrompt) { - sb.append("ShortcutPrompt"); + sb.append("Sp"); // ShortcutPrompt } if (withLicense) { - sb.append("License"); + sb.append("L"); // License } cmd.setArgumentValue("--name", sb.toString()); } From 2fee5de9d883a3ce9295ce818c89b117130e5ea3 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Thu, 9 Jan 2025 03:35:31 +0000 Subject: [PATCH 02/25] 8347297: Skip the RuntimeImageSymbolicLinksTest test on Windows when it is executed outside of the jtreg Reviewed-by: almatvee --- .../tools/jpackage/share/RuntimeImageSymbolicLinksTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java b/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java index db74e3456c4..867ea571213 100644 --- a/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java +++ b/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ import java.nio.file.Files; import java.nio.file.Path; +import static jdk.internal.util.OperatingSystem.WINDOWS; import jdk.jpackage.test.ApplicationLayout; import jdk.jpackage.test.TKit; import jdk.jpackage.test.Annotations.Test; @@ -49,7 +50,7 @@ public class RuntimeImageSymbolicLinksTest { - @Test + @Test(ifNotOS = WINDOWS) public static void test() throws Exception { final Path jmods = Path.of(System.getProperty("java.home"), "jmods"); final Path workDir = TKit.createTempDirectory("runtime").resolve("data"); From f773a50fa1bff931303b2a1527176af03f5bf289 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Thu, 9 Jan 2025 03:42:47 +0000 Subject: [PATCH 03/25] 8347299: Add annotations to test cases in LicenseTest Reviewed-by: almatvee --- .../jdk/tools/jpackage/share/LicenseTest.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/test/jdk/tools/jpackage/share/LicenseTest.java b/test/jdk/tools/jpackage/share/LicenseTest.java index b0eef94fa7c..66cda39eec2 100644 --- a/test/jdk/tools/jpackage/share/LicenseTest.java +++ b/test/jdk/tools/jpackage/share/LicenseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,8 @@ import java.util.Arrays; import java.util.function.Function; import java.util.stream.Collectors; +import static jdk.internal.util.OperatingSystem.LINUX; +import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.PackageTest; @@ -67,6 +69,7 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @compile LicenseTest.java + * @requires (jpackage.test.SQETest != null) * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main * --jpt-run=LicenseTest.testCommon */ @@ -78,18 +81,14 @@ * @key jpackagePlatformPackage * @build jdk.jpackage.test.* * @compile LicenseTest.java - * @requires (os.family == "linux") * @requires (jpackage.test.SQETest == null) * @run main/othervm/timeout=1440 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=LicenseTest.testCustomDebianCopyright - * --jpt-run=LicenseTest.testCustomDebianCopyrightSubst - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree2 - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree3 - * --jpt-run=LicenseTest.testLinuxLicenseInUsrTree4 + * --jpt-run=LicenseTest */ public class LicenseTest { + + @Test public static void testCommon() { PackageTest test = new PackageTest().configureHelloApp() .addInitializer(cmd -> { @@ -102,26 +101,32 @@ public static void testCommon() { test.run(); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree() { testLinuxLicenseInUsrTree("/usr"); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree2() { testLinuxLicenseInUsrTree("/usr/local"); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree3() { testLinuxLicenseInUsrTree("/usr/foo"); } + @Test(ifOS = LINUX) public static void testLinuxLicenseInUsrTree4() { testLinuxLicenseInUsrTree("/usrbuz"); } + @Test(ifOS = LINUX) public static void testCustomDebianCopyright() { new CustomDebianCopyrightTest().run(); } + @Test(ifOS = LINUX) public static void testCustomDebianCopyrightSubst() { new CustomDebianCopyrightTest().withSubstitution(true).run(); } From aaa1c6baf75151f90a1376d0680a88554f259e44 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Thu, 9 Jan 2025 04:11:54 +0000 Subject: [PATCH 04/25] 8339728: [Accessibility,Windows,JAWS] Bug in the getKeyChar method of the AccessBridge class Reviewed-by: aivanov, psadhukhan, kizune --- .../accessibility/internal/AccessBridge.java | 17 ++- .../include/bridge/AccessBridgePackages.h | 4 +- .../TestJMenuItemShortcutAccessibility.java | 112 ++++++++++++++++++ 3 files changed, 122 insertions(+), 11 deletions(-) create mode 100644 test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java diff --git a/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java b/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java index 1f5b5b215fa..021a13fceac 100644 --- a/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java +++ b/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3904,6 +3904,8 @@ private int controlCode(KeyStroke keyStroke) { return 0; int code = keyStroke.getKeyCode(); switch (code) { + case KeyEvent.VK_TAB: + case KeyEvent.VK_SPACE: case KeyEvent.VK_BACK_SPACE: case KeyEvent.VK_DELETE: case KeyEvent.VK_DOWN: @@ -3946,15 +3948,10 @@ private char getKeyChar(KeyStroke keyStroke) { debugString("[INFO]: Shortcut is control character: " + Integer.toHexString(keyCode)); return (char)keyCode; } - String keyText = KeyEvent.getKeyText(keyStroke.getKeyCode()); - debugString("[INFO]: Shortcut is: " + keyText); - if (keyText != null || keyText.length() > 0) { - CharSequence seq = keyText.subSequence(0, 1); - if (seq != null || seq.length() > 0) { - return seq.charAt(0); - } - } - return 0; + + keyCode = keyStroke.getKeyCode(); + debugString("[INFO]: Shortcut is: " + Integer.toHexString(keyCode)); + return (char)keyCode; } /* diff --git a/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h b/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h index 27c31be09a8..232cab4b21b 100644 --- a/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h +++ b/src/jdk.accessibility/windows/native/include/bridge/AccessBridgePackages.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1108,6 +1108,8 @@ typedef long ABHWND64; #define ACCESSIBLE_CONTROLCODE_KEYSTROKE 512 // Control code key pressed, character contains control code. // The supported control code keys are: +#define ACCESSIBLE_VK_TAB 9 +#define ACCESSIBLE_VK_SPACE 32 #define ACCESSIBLE_VK_BACK_SPACE 8 #define ACCESSIBLE_VK_DELETE 127 #define ACCESSIBLE_VK_DOWN 40 diff --git a/test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java b/test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java new file mode 100644 index 00000000000..acd7ec3c64a --- /dev/null +++ b/test/jdk/javax/accessibility/TestJMenuItemShortcutAccessibility.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.KeyStroke; + +/* + * @test + * @bug 8339728 + * @summary Tests that JAWS announce the shortcuts for JMenuItems. + * @requires os.family == "windows" + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @run main/manual TestJMenuItemShortcutAccessibility + */ + +public class TestJMenuItemShortcutAccessibility { + public static void main(String[] args) throws Exception { + String INSTRUCTIONS = """ + 1. Start the JAWS application + 2. Press Alt + M to open application Menu + 3. Navigate the Menu Items by using UP / DOWN arrow key + 4. Press Pass if you are able to hear correct JAWS announcements + (JAWS should read full shortcut text and not only the 1st + character of shortcut text for each menu item) else Fail + """; + + PassFailJFrame.builder() + .title("TestJMenuItemShortcutAccessibility Instruction") + .instructions(INSTRUCTIONS) + .columns(35) + .testUI(TestJMenuItemShortcutAccessibility::createUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createUI() { + JFrame frame = new JFrame("A Frame with Menu"); + + JMenuBar menuBar = new JMenuBar(); + JMenu menu = new JMenu("Menu with shortcuts"); + menu.setMnemonic(KeyEvent.VK_M); + menuBar.add(menu); + + KeyStroke keyStroke1 = KeyStroke.getKeyStroke(KeyEvent.VK_F, + InputEvent.CTRL_DOWN_MASK); + KeyStroke keyStroke2 = KeyStroke.getKeyStroke(KeyEvent.VK_2, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + KeyStroke keyStroke3 = KeyStroke.getKeyStroke(KeyEvent.VK_F1, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + KeyStroke keyStroke4 = KeyStroke.getKeyStroke(KeyEvent.VK_COMMA, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + KeyStroke keyStroke5 = KeyStroke.getKeyStroke(KeyEvent.VK_PERIOD, + InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK); + KeyStroke keyStroke6 = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, + InputEvent.CTRL_DOWN_MASK); + KeyStroke keyStroke7 = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK); + + JMenuItem menuItem1 = new JMenuItem("First Menu Item"); + menuItem1.setAccelerator(keyStroke1); + JMenuItem menuItem2 = new JMenuItem("Second Menu Item"); + menuItem2.setAccelerator(keyStroke2); + JMenuItem menuItem3 = new JMenuItem("Third Menu Item"); + menuItem3.setAccelerator(keyStroke3); + JMenuItem menuItem4 = new JMenuItem("Fourth Menu Item"); + menuItem4.setAccelerator(keyStroke4); + JMenuItem menuItem5 = new JMenuItem("Fifth Menu Item"); + menuItem5.setAccelerator(keyStroke5); + JMenuItem menuItem6 = new JMenuItem("Sixth Menu Item"); + menuItem6.setAccelerator(keyStroke6); + JMenuItem menuItem7 = new JMenuItem("Seventh Menu Item"); + menuItem7.setAccelerator(keyStroke7); + + menu.add(menuItem1); + menu.add(menuItem2); + menu.add(menuItem3); + menu.add(menuItem4); + menu.add(menuItem5); + menu.add(menuItem6); + menu.add(menuItem7); + + frame.setJMenuBar(menuBar); + frame.setSize(300, 200); + return frame; + } +} From f157763b3e7340c994c0078de7bcd3b15c151b32 Mon Sep 17 00:00:00 2001 From: Dmitry Markov Date: Thu, 9 Jan 2025 06:58:31 +0000 Subject: [PATCH 05/25] 8346887: DrawFocusRect() may cause an assertion failure Reviewed-by: aivanov, prr --- .../windows/native/libawt/windows/awt_Button.cpp | 4 ++-- .../windows/native/libawt/windows/awt_Checkbox.cpp | 6 +++--- .../windows/native/libawt/windows/awt_Component.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp index e1dd68a8b50..e59644521ab 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Button.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -242,7 +242,7 @@ AwtButton::OwnerDrawItem(UINT /*ctrlId*/, DRAWITEMSTRUCT& drawInfo) RECT focusRect; VERIFY(::CopyRect(&focusRect, &rect)); VERIFY(::InflateRect(&focusRect,-inf,-inf)); - if(::DrawFocusRect(hDC, &focusRect) == 0) + if (!::IsRectEmpty(&focusRect) && (::DrawFocusRect(hDC, &focusRect) == 0)) VERIFY(::GetLastError() == 0); } diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Checkbox.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Checkbox.cpp index d038783d5f0..b37207fa2eb 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Checkbox.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Checkbox.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -290,13 +290,13 @@ AwtCheckbox::OwnerDrawItem(UINT /*ctrlId*/, DRAWITEMSTRUCT& drawInfo) if ((drawInfo.itemState & ODS_FOCUS) && ((drawInfo.itemAction & ODA_FOCUS)|| (drawInfo.itemAction &ODA_DRAWENTIRE))) { - if(::DrawFocusRect(hDC, &focusRect) == 0) + if (!::IsRectEmpty(&focusRect) && (::DrawFocusRect(hDC, &focusRect) == 0)) VERIFY(::GetLastError() == 0); } /* erase focus rect */ else if (!(drawInfo.itemState & ODS_FOCUS) && (drawInfo.itemAction & ODA_FOCUS)) { - if(::DrawFocusRect(hDC, &focusRect) == 0) + if (!::IsRectEmpty(&focusRect) && (::DrawFocusRect(hDC, &focusRect) == 0)) VERIFY(::GetLastError() == 0); } diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp index c49c2265ca3..b67c5dfcf8d 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -4465,7 +4465,7 @@ void AwtComponent::DrawListItem(JNIEnv *env, DRAWITEMSTRUCT &drawInfo) if ((drawInfo.itemState & ODS_FOCUS) && (drawInfo.itemAction & (ODA_FOCUS | ODA_DRAWENTIRE))) { if (!unfocusableChoice){ - if(::DrawFocusRect(hDC, &rect) == 0) + if (!::IsRectEmpty(&rect) && (::DrawFocusRect(hDC, &rect) == 0)) VERIFY(::GetLastError() == 0); } } From d0cc7994ea67c56ce181da0503bdbf7fccc6f493 Mon Sep 17 00:00:00 2001 From: Ramkumar Sunderbabu Date: Thu, 9 Jan 2025 07:50:42 +0000 Subject: [PATCH 06/25] 8347083: Incomplete logging in nsk/jvmti/ResourceExhausted/resexhausted00* tests Reviewed-by: dholmes, sspitsyn, lmesnik --- .../nsk/jvmti/ResourceExhausted/resexhausted001.java | 4 ++-- .../nsk/jvmti/ResourceExhausted/resexhausted002.java | 4 ++-- .../nsk/jvmti/ResourceExhausted/resexhausted003.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java index b147757f9e0..1009f2d3538 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,7 +62,7 @@ public static int run(String args[], PrintStream out) { makeThread(); } - System.out.println("Can't reproduce OOME due to a limit on iterations/execution time. Test was useless." + System.out.println("Test resexhausted001: Can't reproduce OOME due to a limit on iterations/execution time. Test was useless." + " threadCount=" + threadCount.get()); throw new SkippedException("Test did not get an OutOfMemory error"); diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java index 46832df7dc3..c1a6e111c9f 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted002.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ public static int run(String args[], PrintStream out) { ++count; } - System.out.println("Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); + System.out.println("Test resexhausted002: Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); throw new SkippedException("Test did not get an OutOfMemory error"); } catch (OutOfMemoryError e) { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java index f336c1bf3d5..8cc997fa4ab 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,7 +115,7 @@ public static int run(String args[], PrintStream out) { ++count; } - System.out.println("Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); + System.out.println("Test resexhausted003: Can't reproduce OOME due to a limit on iterations/execution time. Test was useless."); throw new SkippedException("Test did not get an OutOfMemory error"); } catch (OutOfMemoryError e) { From d1c97601796a0aba974ea133110e8ca8ca2a74ca Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 9 Jan 2025 09:49:14 +0000 Subject: [PATCH 07/25] 8347126: gc/stress/TestStressG1Uncommit.java gets OOM-killed Reviewed-by: tschatzl, gli --- test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java b/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java index d04f1acf206..0006ad5ad13 100644 --- a/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java +++ b/test/hotspot/jtreg/gc/stress/TestStressG1Uncommit.java @@ -57,6 +57,7 @@ public static void main(String[] args) throws Exception { Collections.addAll(options, "-Xlog:gc,gc+heap+region=debug", "-XX:+UseG1GC", + "-Xmx1g", StressUncommit.class.getName() ); OutputAnalyzer output = ProcessTools.executeLimitedTestJava(options); @@ -79,9 +80,9 @@ public static void main(String args[]) throws InterruptedException { // Leave 20% head room to try to avoid Full GCs. long allocationSize = (long) (Runtime.getRuntime().maxMemory() * 0.8); - // Figure out suitable number of workers (~1 per gig). - int gigsOfAllocation = (int) Math.ceil((double) allocationSize / G); - int numWorkers = Math.min(gigsOfAllocation, Runtime.getRuntime().availableProcessors()); + // Figure out suitable number of workers (~1 per 100M). + int allocationChunks = (int) Math.ceil((double) allocationSize / (100 * M)); + int numWorkers = Math.min(allocationChunks, Runtime.getRuntime().availableProcessors()); long workerAllocation = allocationSize / numWorkers; log("Using " + numWorkers + " workers, each allocating: ~" + (workerAllocation / M) + "M"); From 441de37536558cd42b62d22f59378fc04f4de527 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Thu, 9 Jan 2025 10:18:08 +0000 Subject: [PATCH 08/25] 8341097: GHA: Demote Mac x86 jobs to build only Reviewed-by: kbarrett, prr, ihse --- .github/workflows/main.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 210d53be658..3ea07501477 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -325,17 +325,6 @@ jobs: bootjdk-platform: linux-x64 runs-on: ubuntu-22.04 - test-macos-x64: - name: macos-x64 - needs: - - build-macos-x64 - uses: ./.github/workflows/test.yml - with: - platform: macos-x64 - bootjdk-platform: macos-x64 - runs-on: macos-13 - xcode-toolset-version: '14.3.1' - test-macos-aarch64: name: macos-aarch64 needs: From ef8e4af116a82cc20f71bf15e58cca0020e8e660 Mon Sep 17 00:00:00 2001 From: Robbin Ehn Date: Thu, 9 Jan 2025 11:25:37 +0000 Subject: [PATCH 09/25] 8346706: RISC-V: Add available registers to hs_err Reviewed-by: mli, fyang, ihse --- make/autoconf/flags-cflags.m4 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index d33f1885922..c1b873ed0ab 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -830,6 +830,22 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP], FLAGS_SETUP_BRANCH_PROTECTION + if test "x$FLAGS_CPU" = xriscv64; then + AC_MSG_CHECKING([if RVV/vector sigcontext supported]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], + [ + return (int)sizeof(struct __riscv_v_ext_state); + ])], + [ + AC_MSG_RESULT([yes]) + ], + [ + $1_DEFINES_CPU_JVM="${$1_DEFINES_CPU_JVM} -DNO_RVV_SIGCONTEXT" + AC_MSG_RESULT([no]) + ] + ) + fi + # EXPORT to API CFLAGS_JVM_COMMON="$ALWAYS_CFLAGS_JVM $ALWAYS_DEFINES_JVM \ $TOOLCHAIN_CFLAGS_JVM ${$1_TOOLCHAIN_CFLAGS_JVM} \ From c8259b9c546183e8458523181836f25f51d381e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Thu, 9 Jan 2025 11:49:18 +0000 Subject: [PATCH 10/25] 8347121: Add missing @serial tags to module java.base Reviewed-by: alanb --- .../lang/EnumConstantNotPresentException.java | 6 +-- .../classes/java/lang/StackTraceElement.java | 18 ++++----- .../java/lang/TypeNotPresentException.java | 4 +- .../AnnotationTypeMismatchException.java | 4 +- .../IncompleteAnnotationException.java | 6 +-- .../java/lang/invoke/SerializedLambda.java | 22 +++++----- .../classes/java/net/HttpRetryException.java | 6 +-- .../classes/java/net/URISyntaxException.java | 6 +-- .../share/classes/java/net/URLPermission.java | 4 +- .../nio/charset/MalformedInputException.java | 4 +- .../charset/UnmappableCharacterException.java | 4 +- .../java/nio/file/FileSystemException.java | 6 +-- .../java/nio/file/InvalidPathException.java | 6 +-- .../UserPrincipalNotFoundException.java | 4 +- .../java/security/AccessControlException.java | 4 +- .../classes/java/security/AllPermission.java | 4 +- .../classes/java/security/GuardedObject.java | 6 +-- .../share/classes/java/security/KeyPair.java | 6 +-- .../classes/java/security/Permission.java | 4 +- .../java/security/PermissionCollection.java | 4 +- .../classes/java/security/Permissions.java | 3 +- .../classes/java/security/SignedObject.java | 8 ++-- .../classes/java/security/cert/CertPath.java | 6 +-- .../java/security/cert/Certificate.java | 6 +-- .../share/classes/java/text/DateFormat.java | 4 +- .../share/classes/java/time/Duration.java | 6 +-- .../share/classes/java/time/Instant.java | 6 +-- .../share/classes/java/time/LocalDate.java | 8 ++-- .../classes/java/time/LocalDateTime.java | 6 +-- .../share/classes/java/time/LocalTime.java | 10 ++--- .../share/classes/java/time/MonthDay.java | 6 +-- .../classes/java/time/OffsetDateTime.java | 6 +-- .../share/classes/java/time/OffsetTime.java | 6 +-- .../share/classes/java/time/Period.java | 8 ++-- .../share/classes/java/time/Year.java | 4 +- .../share/classes/java/time/YearMonth.java | 6 +-- .../share/classes/java/time/ZoneOffset.java | 4 +- .../classes/java/time/ZonedDateTime.java | 8 ++-- .../time/format/DateTimeParseException.java | 6 +-- .../java/time/temporal/ValueRange.java | 10 ++--- .../java/time/temporal/WeekFields.java | 6 +-- .../java/time/zone/ZoneOffsetTransition.java | 10 ++--- .../time/zone/ZoneOffsetTransitionRule.java | 20 +++++----- .../classes/java/time/zone/ZoneRules.java | 14 +++---- .../share/classes/java/util/AbstractMap.java | 6 ++- .../share/classes/java/util/Arrays.java | 3 +- .../share/classes/java/util/Collections.java | 40 +++++++++++++++++-- .../util/DuplicateFormatFlagsException.java | 3 +- ...ormatFlagsConversionMismatchException.java | 4 +- .../util/IllegalFormatCodePointException.java | 3 +- .../IllegalFormatConversionException.java | 4 +- .../util/IllegalFormatFlagsException.java | 3 +- .../util/IllegalFormatPrecisionException.java | 3 +- .../util/IllegalFormatWidthException.java | 3 +- .../java/util/IllformedLocaleException.java | 3 +- .../util/MissingFormatArgumentException.java | 3 +- .../util/MissingFormatWidthException.java | 3 +- .../classes/java/util/PriorityQueue.java | 6 +-- .../share/classes/java/util/TreeMap.java | 13 ++++-- .../share/classes/java/util/UUID.java | 14 +++---- .../UnknownFormatConversionException.java | 3 +- .../util/UnknownFormatFlagsException.java | 3 +- .../util/concurrent/ArrayBlockingQueue.java | 14 +++---- .../util/concurrent/ConcurrentHashMap.java | 1 + .../concurrent/ConcurrentSkipListMap.java | 12 +++--- .../concurrent/ConcurrentSkipListSet.java | 2 +- .../util/concurrent/CopyOnWriteArraySet.java | 1 + .../util/concurrent/CountedCompleter.java | 4 +- .../java/util/concurrent/ForkJoinTask.java | 1 + .../util/concurrent/LinkedBlockingDeque.java | 8 ++-- .../util/concurrent/LinkedBlockingQueue.java | 12 +++--- .../concurrent/PriorityBlockingQueue.java | 6 +-- .../java/util/concurrent/RecursiveTask.java | 2 +- .../java/util/concurrent/Semaphore.java | 2 +- .../util/concurrent/SynchronousQueue.java | 3 ++ .../util/concurrent/atomic/AtomicBoolean.java | 1 + .../util/concurrent/atomic/AtomicInteger.java | 1 + .../concurrent/atomic/AtomicIntegerArray.java | 1 + .../util/concurrent/atomic/AtomicLong.java | 1 + .../concurrent/atomic/AtomicLongArray.java | 1 + .../concurrent/atomic/AtomicReference.java | 1 + .../atomic/AtomicReferenceArray.java | 1 + .../concurrent/atomic/DoubleAccumulator.java | 2 + .../concurrent/atomic/LongAccumulator.java | 2 + .../locks/AbstractQueuedLongSynchronizer.java | 2 +- .../locks/AbstractQueuedSynchronizer.java | 2 +- .../util/concurrent/locks/ReentrantLock.java | 2 +- .../locks/ReentrantReadWriteLock.java | 8 ++-- .../util/regex/PatternSyntaxException.java | 5 ++- 89 files changed, 301 insertions(+), 222 deletions(-) diff --git a/src/java.base/share/classes/java/lang/EnumConstantNotPresentException.java b/src/java.base/share/classes/java/lang/EnumConstantNotPresentException.java index 4ba7cd3b175..cdab2081181 100644 --- a/src/java.base/share/classes/java/lang/EnumConstantNotPresentException.java +++ b/src/java.base/share/classes/java/lang/EnumConstantNotPresentException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,12 +42,12 @@ public class EnumConstantNotPresentException extends RuntimeException { private static final long serialVersionUID = -6046998521960521108L; /** - * The type of the missing enum constant. + * @serial The type of the missing enum constant. */ private Class enumType; /** - * The name of the missing enum constant. + * @serial The name of the missing enum constant. */ private String constantName; diff --git a/src/java.base/share/classes/java/lang/StackTraceElement.java b/src/java.base/share/classes/java/lang/StackTraceElement.java index ed8d47a4e50..70219a7f6ec 100644 --- a/src/java.base/share/classes/java/lang/StackTraceElement.java +++ b/src/java.base/share/classes/java/lang/StackTraceElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,35 +64,35 @@ public final class StackTraceElement implements java.io.Serializable { // Normally initialized by VM /** - * The name of the class loader. + * @serial The name of the class loader. */ private String classLoaderName; /** - * The module name. + * @serial The module name. */ private String moduleName; /** - * The module version. + * @serial The module version. */ private String moduleVersion; /** - * The declaring class. + * @serial The declaring class. */ private String declaringClass; /** - * The method name. + * @serial The method name. */ private String methodName; /** - * The source file name. + * @serial The source file name. */ private String fileName; /** - * The source line number. + * @serial The source line number. */ private int lineNumber; /** - * Control to show full or partial module, package, and class names. + * @serial Control to show full or partial module, package, and class names. */ private byte format = 0; // Default to show all diff --git a/src/java.base/share/classes/java/lang/TypeNotPresentException.java b/src/java.base/share/classes/java/lang/TypeNotPresentException.java index c5a899ef285..5ba43efbc09 100644 --- a/src/java.base/share/classes/java/lang/TypeNotPresentException.java +++ b/src/java.base/share/classes/java/lang/TypeNotPresentException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ public class TypeNotPresentException extends RuntimeException { private static final long serialVersionUID = -5101214195716534496L; /** - * The type name or the name of a type variable. + * @serial The type name or the name of a type variable. */ private String typeName; diff --git a/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java b/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java index 6a9ea51d10b..83054044b60 100644 --- a/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java +++ b/src/java.base/share/classes/java/lang/annotation/AnnotationTypeMismatchException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ public class AnnotationTypeMismatchException extends RuntimeException { private final transient Method element; /** - * The (erroneous) type of data found in the annotation. This string + * @serial The (erroneous) type of data found in the annotation. This string * may, but is not required to, contain the value as well. The exact * format of the string is unspecified. */ diff --git a/src/java.base/share/classes/java/lang/annotation/IncompleteAnnotationException.java b/src/java.base/share/classes/java/lang/annotation/IncompleteAnnotationException.java index 921d4b92fcd..02f2638c370 100644 --- a/src/java.base/share/classes/java/lang/annotation/IncompleteAnnotationException.java +++ b/src/java.base/share/classes/java/lang/annotation/IncompleteAnnotationException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,11 +43,11 @@ public class IncompleteAnnotationException extends RuntimeException { private static final long serialVersionUID = 8445097402741811912L; /** - * The annotation interface. + * @serial The annotation interface. */ private Class annotationType; /** - * The element name. + * @serial The element name. */ private String elementName; diff --git a/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java b/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java index 3767bf23388..3ffe3c9a9f2 100644 --- a/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java +++ b/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,43 +65,43 @@ public final class SerializedLambda implements Serializable { @java.io.Serial private static final long serialVersionUID = 8025925345765570181L; /** - * The capturing class. + * @serial The capturing class. */ private final Class capturingClass; /** - * The functional interface class. + * @serial The functional interface class. */ private final String functionalInterfaceClass; /** - * The functional interface method name. + * @serial The functional interface method name. */ private final String functionalInterfaceMethodName; /** - * The functional interface method signature. + * @serial The functional interface method signature. */ private final String functionalInterfaceMethodSignature; /** - * The implementation class. + * @serial The implementation class. */ private final String implClass; /** - * The implementation method name. + * @serial The implementation method name. */ private final String implMethodName; /** - * The implementation method signature. + * @serial The implementation method signature. */ private final String implMethodSignature; /** - * The implementation method kind. + * @serial The implementation method kind. */ private final int implMethodKind; /** - * The instantiated method type. + * @serial The instantiated method type. */ private final String instantiatedMethodType; /** - * The captured arguments. + * @serial The captured arguments. */ @SuppressWarnings("serial") // Not statically typed as Serializable private final Object[] capturedArgs; diff --git a/src/java.base/share/classes/java/net/HttpRetryException.java b/src/java.base/share/classes/java/net/HttpRetryException.java index fefeb9bb687..6d41ac3b563 100644 --- a/src/java.base/share/classes/java/net/HttpRetryException.java +++ b/src/java.base/share/classes/java/net/HttpRetryException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,12 +40,12 @@ public class HttpRetryException extends IOException { private static final long serialVersionUID = -9186022286469111381L; /** - * The response code. + * @serial The response code. */ private final int responseCode; /** - * The URL to be redirected to. + * @serial The URL to be redirected to. */ private String location; diff --git a/src/java.base/share/classes/java/net/URISyntaxException.java b/src/java.base/share/classes/java/net/URISyntaxException.java index 3b9889cd1b4..c0b0cbdd234 100644 --- a/src/java.base/share/classes/java/net/URISyntaxException.java +++ b/src/java.base/share/classes/java/net/URISyntaxException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,12 +42,12 @@ public class URISyntaxException private static final long serialVersionUID = 2137979680897488891L; /** - * The input string. + * @serial The input string. */ private final String input; /** - * The index at which the parse error occurred, + * @serial The index at which the parse error occurred, * or {@code -1} if the index is not known. */ private final int index; diff --git a/src/java.base/share/classes/java/net/URLPermission.java b/src/java.base/share/classes/java/net/URLPermission.java index d48f784ff84..daf3e99a6a0 100644 --- a/src/java.base/share/classes/java/net/URLPermission.java +++ b/src/java.base/share/classes/java/net/URLPermission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -168,7 +168,7 @@ public final class URLPermission extends Permission { // serialized field /** - * The actions string + * @serial The actions string */ private String actions; diff --git a/src/java.base/share/classes/java/nio/charset/MalformedInputException.java b/src/java.base/share/classes/java/nio/charset/MalformedInputException.java index c36f81f9153..a4e7f31fc2c 100644 --- a/src/java.base/share/classes/java/nio/charset/MalformedInputException.java +++ b/src/java.base/share/classes/java/nio/charset/MalformedInputException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ public class MalformedInputException private static final long serialVersionUID = -3438823399834806194L; /** - * The length of the input. + * @serial The length of the input. */ private int inputLength; diff --git a/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java b/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java index 857c519974d..8f79a232f03 100644 --- a/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java +++ b/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ public class UnmappableCharacterException private static final long serialVersionUID = -7026962371537706123L; /** - * The length of the input character (or byte) sequence. + * @serial The length of the input character (or byte) sequence. */ private int inputLength; diff --git a/src/java.base/share/classes/java/nio/file/FileSystemException.java b/src/java.base/share/classes/java/nio/file/FileSystemException.java index a03a2708ce6..43887756b15 100644 --- a/src/java.base/share/classes/java/nio/file/FileSystemException.java +++ b/src/java.base/share/classes/java/nio/file/FileSystemException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,12 +41,12 @@ public class FileSystemException static final long serialVersionUID = -3055425747967319812L; /** - * String identifying the file or {@code null} if not known. + * @serial String identifying the file or {@code null} if not known. */ private final String file; /** - * String identifying the other file or {@code null} if there isn't + * @serial String identifying the other file or {@code null} if there isn't * another file or if not known. */ private final String other; diff --git a/src/java.base/share/classes/java/nio/file/InvalidPathException.java b/src/java.base/share/classes/java/nio/file/InvalidPathException.java index bb28b61b83b..495d087a39d 100644 --- a/src/java.base/share/classes/java/nio/file/InvalidPathException.java +++ b/src/java.base/share/classes/java/nio/file/InvalidPathException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,12 +40,12 @@ public class InvalidPathException static final long serialVersionUID = 4355821422286746137L; /** - * The input string. + * @serial The input string. */ private String input; /** - * The index of the input string at which the error occurred or + * @serial The index of the input string at which the error occurred or * {@code -1} if not known. */ private int index; diff --git a/src/java.base/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java b/src/java.base/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java index 209453cdaad..9baca303ef0 100644 --- a/src/java.base/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java +++ b/src/java.base/share/classes/java/nio/file/attribute/UserPrincipalNotFoundException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,7 @@ public class UserPrincipalNotFoundException static final long serialVersionUID = -5369283889045833024L; /** - * The user principal name. + * @serial The user principal name. */ private final String name; diff --git a/src/java.base/share/classes/java/security/AccessControlException.java b/src/java.base/share/classes/java/security/AccessControlException.java index 4d46cd6887e..d423d95513d 100644 --- a/src/java.base/share/classes/java/security/AccessControlException.java +++ b/src/java.base/share/classes/java/security/AccessControlException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ public class AccessControlException extends SecurityException { private static final long serialVersionUID = 5138225684096988535L; /** - * The permission that caused the exception to be thrown. + * @serial The permission that caused the exception to be thrown. */ private Permission perm; diff --git a/src/java.base/share/classes/java/security/AllPermission.java b/src/java.base/share/classes/java/security/AllPermission.java index 15a4f78123f..23c55085ec3 100644 --- a/src/java.base/share/classes/java/security/AllPermission.java +++ b/src/java.base/share/classes/java/security/AllPermission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -151,7 +151,7 @@ final class AllPermissionCollection private static final long serialVersionUID = -4023755556366636806L; /** - * True if any {@code AllPermissionCollection} objects have been added. + * @serial True if any {@code AllPermissionCollection} objects have been added. */ private boolean all_allowed; diff --git a/src/java.base/share/classes/java/security/GuardedObject.java b/src/java.base/share/classes/java/security/GuardedObject.java index 2c9d1a345dc..fedb0eeae1d 100644 --- a/src/java.base/share/classes/java/security/GuardedObject.java +++ b/src/java.base/share/classes/java/security/GuardedObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,13 +55,13 @@ public class GuardedObject implements java.io.Serializable { private static final long serialVersionUID = -5240450096227834308L; /** - * The object we are guarding. + * @serial The object we are guarding. */ @SuppressWarnings("serial") // Not statically typed as Serializable private final Object object; /** - * The guard object. + * @serial The guard object. */ @SuppressWarnings("serial") // Not statically typed as Serializable private final Guard guard; diff --git a/src/java.base/share/classes/java/security/KeyPair.java b/src/java.base/share/classes/java/security/KeyPair.java index 61c1121bdee..cc648a677dd 100644 --- a/src/java.base/share/classes/java/security/KeyPair.java +++ b/src/java.base/share/classes/java/security/KeyPair.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,10 +42,10 @@ public final class KeyPair implements java.io.Serializable { @java.io.Serial private static final long serialVersionUID = -7565189502268009837L; - /** The private key. */ + /** @serial The private key. */ private final PrivateKey privateKey; - /** The public key. */ + /** @serial The public key. */ private final PublicKey publicKey; /** diff --git a/src/java.base/share/classes/java/security/Permission.java b/src/java.base/share/classes/java/security/Permission.java index 71bad14e395..e066bc0e591 100644 --- a/src/java.base/share/classes/java/security/Permission.java +++ b/src/java.base/share/classes/java/security/Permission.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,7 +69,7 @@ public abstract class Permission implements Guard, java.io.Serializable { private static final long serialVersionUID = -5636570222231596674L; /** - * The permission name. + * @serial The permission name. */ private final String name; diff --git a/src/java.base/share/classes/java/security/PermissionCollection.java b/src/java.base/share/classes/java/security/PermissionCollection.java index d287a685059..3718744c349 100644 --- a/src/java.base/share/classes/java/security/PermissionCollection.java +++ b/src/java.base/share/classes/java/security/PermissionCollection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,7 +103,7 @@ public abstract class PermissionCollection implements java.io.Serializable { private static final long serialVersionUID = -6727011328946861783L; /** - * Whether this permission collection is read-only. + * @serial Whether this permission collection is read-only. *

* If set, the {@code add} method will throw an exception. */ diff --git a/src/java.base/share/classes/java/security/Permissions.java b/src/java.base/share/classes/java/security/Permissions.java index 3bdeac6f929..ecb18aca8bb 100644 --- a/src/java.base/share/classes/java/security/Permissions.java +++ b/src/java.base/share/classes/java/security/Permissions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,6 +92,7 @@ public final class Permissions extends PermissionCollection // checked private transient boolean hasUnresolved = false; + /** @serial */ // optimization. keep track of the AllPermission collection // - package private for ProtectionDomain optimization PermissionCollection allPermission; diff --git a/src/java.base/share/classes/java/security/SignedObject.java b/src/java.base/share/classes/java/security/SignedObject.java index f65300fc808..d1b203c3aea 100644 --- a/src/java.base/share/classes/java/security/SignedObject.java +++ b/src/java.base/share/classes/java/security/SignedObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -122,18 +122,18 @@ public final class SignedObject implements Serializable { private static final long serialVersionUID = 720502720485447167L; /** - * The original content is "deep copied" in its serialized format + * @serial The original content is "deep copied" in its serialized format * and stored in a byte array. */ private byte[] content; /** - * The signature field is stored as a byte array. + * @serial The signature field is stored as a byte array. */ private byte[] signature; /** - * The algorithm used to sign the object. + * @serial The algorithm used to sign the object. */ private String thealgorithm; diff --git a/src/java.base/share/classes/java/security/cert/CertPath.java b/src/java.base/share/classes/java/security/cert/CertPath.java index 80e68d1c598..ffbbf0291b1 100644 --- a/src/java.base/share/classes/java/security/cert/CertPath.java +++ b/src/java.base/share/classes/java/security/cert/CertPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -301,9 +301,9 @@ protected static class CertPathRep implements Serializable { @java.io.Serial private static final long serialVersionUID = 3015633072427920915L; - /** The type of {@code Certificate}s in the {@code CertPath}. */ + /** @serial The type of {@code Certificate}s in the {@code CertPath}. */ private final String type; - /** The encoded form of the {@code CertPath}. */ + /** @serial The encoded form of the {@code CertPath}. */ private final byte[] data; /** diff --git a/src/java.base/share/classes/java/security/cert/Certificate.java b/src/java.base/share/classes/java/security/cert/Certificate.java index 1e212f644b3..618026c894d 100644 --- a/src/java.base/share/classes/java/security/cert/Certificate.java +++ b/src/java.base/share/classes/java/security/cert/Certificate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -244,10 +244,10 @@ protected static class CertificateRep implements java.io.Serializable { @java.io.Serial private static final long serialVersionUID = -8563758940495660020L; - /** The standard name of the certificate type. */ + /** @serial The standard name of the certificate type. */ private final String type; - /** The certificate data. */ + /** @serial The certificate data. */ private final byte[] data; /** diff --git a/src/java.base/share/classes/java/text/DateFormat.java b/src/java.base/share/classes/java/text/DateFormat.java index e29b3f0509f..af756289086 100644 --- a/src/java.base/share/classes/java/text/DateFormat.java +++ b/src/java.base/share/classes/java/text/DateFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -953,7 +953,7 @@ public static class Field extends Format.Field { private static final Field[] calendarToFieldMapping = new Field[Calendar.FIELD_COUNT]; - /** Calendar field. */ + /** @serial Calendar field. */ private int calendarField; /** diff --git a/src/java.base/share/classes/java/time/Duration.java b/src/java.base/share/classes/java/time/Duration.java index 402ecba7728..d640121f32d 100644 --- a/src/java.base/share/classes/java/time/Duration.java +++ b/src/java.base/share/classes/java/time/Duration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -158,11 +158,11 @@ private static class Lazy { } /** - * The number of seconds in the duration. + * @serial The number of seconds in the duration. */ private final long seconds; /** - * The number of nanoseconds in the duration, expressed as a fraction of the + * @serial The number of nanoseconds in the duration, expressed as a fraction of the * number of seconds. This is always positive, and never exceeds 999,999,999. */ private final int nanos; diff --git a/src/java.base/share/classes/java/time/Instant.java b/src/java.base/share/classes/java/time/Instant.java index 05358cc4f3c..82ff18c1421 100644 --- a/src/java.base/share/classes/java/time/Instant.java +++ b/src/java.base/share/classes/java/time/Instant.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -252,11 +252,11 @@ public final class Instant private static final long serialVersionUID = -665713676816604388L; /** - * The number of seconds from the epoch of 1970-01-01T00:00:00Z. + * @serial The number of seconds from the epoch of 1970-01-01T00:00:00Z. */ private final long seconds; /** - * The number of nanoseconds, later along the time-line, from the seconds field. + * @serial The number of nanoseconds, later along the time-line, from the seconds field. * This is always positive, and never exceeds 999,999,999. */ private final int nanos; diff --git a/src/java.base/share/classes/java/time/LocalDate.java b/src/java.base/share/classes/java/time/LocalDate.java index 2d71fb1ceca..caf6ccd6641 100644 --- a/src/java.base/share/classes/java/time/LocalDate.java +++ b/src/java.base/share/classes/java/time/LocalDate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -174,15 +174,15 @@ public final class LocalDate static final long DAYS_0000_TO_1970 = (DAYS_PER_CYCLE * 5L) - (30L * 365L + 7L); /** - * The year. + * @serial The year. */ private final int year; /** - * The month-of-year. + * @serial The month-of-year. */ private final short month; /** - * The day-of-month. + * @serial The day-of-month. */ private final short day; diff --git a/src/java.base/share/classes/java/time/LocalDateTime.java b/src/java.base/share/classes/java/time/LocalDateTime.java index cea9123258c..f8c814957dc 100644 --- a/src/java.base/share/classes/java/time/LocalDateTime.java +++ b/src/java.base/share/classes/java/time/LocalDateTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -158,11 +158,11 @@ public final class LocalDateTime private static final long serialVersionUID = 6207766400415563566L; /** - * The date part. + * @serial The date part. */ private final LocalDate date; /** - * The time part. + * @serial The time part. */ private final LocalTime time; diff --git a/src/java.base/share/classes/java/time/LocalTime.java b/src/java.base/share/classes/java/time/LocalTime.java index f28f8d3c599..06f408350ca 100644 --- a/src/java.base/share/classes/java/time/LocalTime.java +++ b/src/java.base/share/classes/java/time/LocalTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -228,19 +228,19 @@ public final class LocalTime private static final long serialVersionUID = 6414437269572265201L; /** - * The hour. + * @serial The hour. */ private final byte hour; /** - * The minute. + * @serial The minute. */ private final byte minute; /** - * The second. + * @serial The second. */ private final byte second; /** - * The nanosecond. + * @serial The nanosecond. */ private final int nano; diff --git a/src/java.base/share/classes/java/time/MonthDay.java b/src/java.base/share/classes/java/time/MonthDay.java index acb3087a5e5..1de4fa84d3e 100644 --- a/src/java.base/share/classes/java/time/MonthDay.java +++ b/src/java.base/share/classes/java/time/MonthDay.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -144,11 +144,11 @@ public final class MonthDay .toFormatter(); /** - * The month-of-year, not null. + * @serial The month-of-year, not null. */ private final int month; /** - * The day-of-month. + * @serial The day-of-month. */ private final int day; diff --git a/src/java.base/share/classes/java/time/OffsetDateTime.java b/src/java.base/share/classes/java/time/OffsetDateTime.java index fd8355e36cd..6f7005b9fa4 100644 --- a/src/java.base/share/classes/java/time/OffsetDateTime.java +++ b/src/java.base/share/classes/java/time/OffsetDateTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -190,11 +190,11 @@ private static int compareInstant(OffsetDateTime datetime1, OffsetDateTime datet private static final long serialVersionUID = 2287754244819255394L; /** - * The local date-time. + * @serial The local date-time. */ private final LocalDateTime dateTime; /** - * The offset from UTC/Greenwich. + * @serial The offset from UTC/Greenwich. */ private final ZoneOffset offset; diff --git a/src/java.base/share/classes/java/time/OffsetTime.java b/src/java.base/share/classes/java/time/OffsetTime.java index 1f6feb4180f..ad9781e2459 100644 --- a/src/java.base/share/classes/java/time/OffsetTime.java +++ b/src/java.base/share/classes/java/time/OffsetTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -143,11 +143,11 @@ public final class OffsetTime private static final long serialVersionUID = 7264499704384272492L; /** - * The local date-time. + * @serial The local date-time. */ private final LocalTime time; /** - * The offset from UTC/Greenwich. + * @serial The offset from UTC/Greenwich. */ private final ZoneOffset offset; diff --git a/src/java.base/share/classes/java/time/Period.java b/src/java.base/share/classes/java/time/Period.java index 40cad4cac59..5ee80710edb 100644 --- a/src/java.base/share/classes/java/time/Period.java +++ b/src/java.base/share/classes/java/time/Period.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -155,15 +155,15 @@ public final class Period private static final List SUPPORTED_UNITS = List.of(YEARS, MONTHS, DAYS); /** - * The number of years. + * @serial The number of years. */ private final int years; /** - * The number of months. + * @serial The number of months. */ private final int months; /** - * The number of days. + * @serial The number of days. */ private final int days; diff --git a/src/java.base/share/classes/java/time/Year.java b/src/java.base/share/classes/java/time/Year.java index cdcaa390320..97264ab8c1c 100644 --- a/src/java.base/share/classes/java/time/Year.java +++ b/src/java.base/share/classes/java/time/Year.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -159,7 +159,7 @@ public final class Year .toFormatter(); /** - * The year being represented. + * @serial The year being represented. */ private final int year; diff --git a/src/java.base/share/classes/java/time/YearMonth.java b/src/java.base/share/classes/java/time/YearMonth.java index 201c01a2193..8ad1172811f 100644 --- a/src/java.base/share/classes/java/time/YearMonth.java +++ b/src/java.base/share/classes/java/time/YearMonth.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -147,11 +147,11 @@ public final class YearMonth .toFormatter(); /** - * The year. + * @serial The year. */ private final int year; /** - * The month-of-year, not null. + * @serial The month-of-year, not null. */ private final int month; diff --git a/src/java.base/share/classes/java/time/ZoneOffset.java b/src/java.base/share/classes/java/time/ZoneOffset.java index 520a0e0b9a1..48f2a2ded22 100644 --- a/src/java.base/share/classes/java/time/ZoneOffset.java +++ b/src/java.base/share/classes/java/time/ZoneOffset.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -163,7 +163,7 @@ public final class ZoneOffset public static final ZoneOffset MAX = ZoneOffset.ofTotalSeconds(MAX_SECONDS); /** - * The total offset in seconds. + * @serial The total offset in seconds. */ private final int totalSeconds; /** diff --git a/src/java.base/share/classes/java/time/ZonedDateTime.java b/src/java.base/share/classes/java/time/ZonedDateTime.java index b1426efc914..135d1a16ae7 100644 --- a/src/java.base/share/classes/java/time/ZonedDateTime.java +++ b/src/java.base/share/classes/java/time/ZonedDateTime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -172,15 +172,15 @@ public final class ZonedDateTime private static final long serialVersionUID = -6260982410461394882L; /** - * The local date-time. + * @serial The local date-time. */ private final LocalDateTime dateTime; /** - * The offset from UTC/Greenwich. + * @serial The offset from UTC/Greenwich. */ private final ZoneOffset offset; /** - * The time-zone. + * @serial The time-zone. */ private final ZoneId zone; diff --git a/src/java.base/share/classes/java/time/format/DateTimeParseException.java b/src/java.base/share/classes/java/time/format/DateTimeParseException.java index e9dd56b02ff..4bf69fdeb12 100644 --- a/src/java.base/share/classes/java/time/format/DateTimeParseException.java +++ b/src/java.base/share/classes/java/time/format/DateTimeParseException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,11 +82,11 @@ public class DateTimeParseException extends DateTimeException { private static final long serialVersionUID = 4304633501674722597L; /** - * The text that was being parsed. + * @serial The text that was being parsed. */ private final String parsedString; /** - * The error index in the text. + * @serial The error index in the text. */ private final int errorIndex; diff --git a/src/java.base/share/classes/java/time/temporal/ValueRange.java b/src/java.base/share/classes/java/time/temporal/ValueRange.java index 78a13420877..442cf0a2509 100644 --- a/src/java.base/share/classes/java/time/temporal/ValueRange.java +++ b/src/java.base/share/classes/java/time/temporal/ValueRange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -96,19 +96,19 @@ public final class ValueRange implements Serializable { private static final long serialVersionUID = -7317881728594519368L; /** - * The smallest minimum value. + * @serial The smallest minimum value. */ private final long minSmallest; /** - * The largest minimum value. + * @serial The largest minimum value. */ private final long minLargest; /** - * The smallest maximum value. + * @serial The smallest maximum value. */ private final long maxSmallest; /** - * The largest maximum value. + * @serial The largest maximum value. */ private final long maxLargest; diff --git a/src/java.base/share/classes/java/time/temporal/WeekFields.java b/src/java.base/share/classes/java/time/temporal/WeekFields.java index 9b687017a36..bbad365553d 100644 --- a/src/java.base/share/classes/java/time/temporal/WeekFields.java +++ b/src/java.base/share/classes/java/time/temporal/WeekFields.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -247,11 +247,11 @@ public final class WeekFields implements Serializable { private static final long serialVersionUID = -1177360819670808121L; /** - * The first day-of-week. + * @serial The first day-of-week. */ private final DayOfWeek firstDayOfWeek; /** - * The minimal number of days in the first week. + * @serial The minimal number of days in the first week. */ private final int minimalDays; /** diff --git a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java index f5d27a0cae0..1e358b9295d 100644 --- a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java +++ b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,19 +104,19 @@ public final class ZoneOffsetTransition */ private static final long serialVersionUID = -6946044323557704546L; /** - * The transition epoch-second. + * @serial The transition epoch-second. */ private final long epochSecond; /** - * The local transition date-time at the transition. + * @serial The local transition date-time at the transition. */ private final LocalDateTime transition; /** - * The offset before transition. + * @serial The offset before transition. */ private final ZoneOffset offsetBefore; /** - * The offset after transition. + * @serial The offset after transition. */ private final ZoneOffset offsetAfter; diff --git a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java index 8eb232075fe..129aae8c27f 100644 --- a/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java +++ b/src/java.base/share/classes/java/time/zone/ZoneOffsetTransitionRule.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,12 +105,12 @@ public final class ZoneOffsetTransitionRule implements Serializable { private static final long serialVersionUID = 6889046316657758795L; /** - * The month of the month-day of the first day of the cutover week. + * @serial The month of the month-day of the first day of the cutover week. * The actual date will be adjusted by the dowChange field. */ private final Month month; /** - * The day-of-month of the month-day of the cutover week. + * @serial The day-of-month of the month-day of the cutover week. * If positive, it is the start of the week where the cutover can occur. * If negative, it represents the end of the week where cutover can occur. * The value is the number of days from the end of the month, such that @@ -119,31 +119,31 @@ public final class ZoneOffsetTransitionRule implements Serializable { */ private final byte dom; /** - * The cutover day-of-week, null to retain the day-of-month. + * @serial The cutover day-of-week, null to retain the day-of-month. */ private final DayOfWeek dow; /** - * The cutover time in the 'before' offset. + * @serial The cutover time in the 'before' offset. */ private final LocalTime time; /** - * Whether the cutover time is midnight at the end of day. + * @serial Whether the cutover time is midnight at the end of day. */ private final boolean timeEndOfDay; /** - * The definition of how the local time should be interpreted. + * @serial The definition of how the local time should be interpreted. */ private final TimeDefinition timeDefinition; /** - * The standard offset at the cutover. + * @serial The standard offset at the cutover. */ private final ZoneOffset standardOffset; /** - * The offset before the cutover. + * @serial The offset before the cutover. */ private final ZoneOffset offsetBefore; /** - * The offset after the cutover. + * @serial The offset after the cutover. */ private final ZoneOffset offsetAfter; diff --git a/src/java.base/share/classes/java/time/zone/ZoneRules.java b/src/java.base/share/classes/java/time/zone/ZoneRules.java index 5945e801f15..788c080fc17 100644 --- a/src/java.base/share/classes/java/time/zone/ZoneRules.java +++ b/src/java.base/share/classes/java/time/zone/ZoneRules.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,29 +118,29 @@ public final class ZoneRules implements Serializable { private static final int LAST_CACHED_YEAR = 2100; /** - * The transitions between standard offsets (epoch seconds), sorted. + * @serial The transitions between standard offsets (epoch seconds), sorted. */ private final long[] standardTransitions; /** - * The standard offsets. + * @serial The standard offsets. */ private final ZoneOffset[] standardOffsets; /** - * The transitions between instants (epoch seconds), sorted. + * @serial The transitions between instants (epoch seconds), sorted. */ private final long[] savingsInstantTransitions; /** - * The transitions between local date-times, sorted. + * @serial The transitions between local date-times, sorted. * This is a paired array, where the first entry is the start of the transition * and the second entry is the end of the transition. */ private final LocalDateTime[] savingsLocalTransitions; /** - * The wall offsets. + * @serial The wall offsets. */ private final ZoneOffset[] wallOffsets; /** - * The last rule. + * @serial The last rule. */ private final ZoneOffsetTransitionRule[] lastRules; /** diff --git a/src/java.base/share/classes/java/util/AbstractMap.java b/src/java.base/share/classes/java/util/AbstractMap.java index c5ea53e17db..7c0b4d9dd1b 100644 --- a/src/java.base/share/classes/java/util/AbstractMap.java +++ b/src/java.base/share/classes/java/util/AbstractMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -587,8 +587,10 @@ public static class SimpleEntry @java.io.Serial private static final long serialVersionUID = -8499721149061103585L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final K key; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private V value; @@ -733,8 +735,10 @@ public static class SimpleImmutableEntry @java.io.Serial private static final long serialVersionUID = 7138329143949025153L; + /** @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable private final K key; + /** @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable private final V value; diff --git a/src/java.base/share/classes/java/util/Arrays.java b/src/java.base/share/classes/java/util/Arrays.java index 03fdf7a3c99..657b8123ec5 100644 --- a/src/java.base/share/classes/java/util/Arrays.java +++ b/src/java.base/share/classes/java/util/Arrays.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -4189,6 +4189,7 @@ private static class ArrayList extends AbstractList { @java.io.Serial private static final long serialVersionUID = -2764017481108945198L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final E[] a; diff --git a/src/java.base/share/classes/java/util/Collections.java b/src/java.base/share/classes/java/util/Collections.java index 4ec5756f712..2afb94af114 100644 --- a/src/java.base/share/classes/java/util/Collections.java +++ b/src/java.base/share/classes/java/util/Collections.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1054,6 +1054,7 @@ static class UnmodifiableCollection implements Collection, Serializable { @java.io.Serial private static final long serialVersionUID = 1820017752578914078L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Collection c; @@ -1337,6 +1338,7 @@ static class UnmodifiableSortedSet implements SortedSet, Serializable { @java.io.Serial private static final long serialVersionUID = -4929149591599911165L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedSet ss; @@ -1419,7 +1421,7 @@ public EmptyNavigableSet() { new EmptyNavigableSet<>(); /** - * The instance we are protecting. + * @serial The instance we are protecting. */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableSet ns; @@ -1488,6 +1490,7 @@ static class UnmodifiableList extends UnmodifiableCollection @java.io.Serial private static final long serialVersionUID = -283967356065247728L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final List list; @@ -1641,6 +1644,7 @@ private static class UnmodifiableMap implements Map, Serializable { @java.io.Serial private static final long serialVersionUID = -1034234728574286014L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Map m; @@ -2068,6 +2072,7 @@ static class UnmodifiableSortedMap @java.io.Serial private static final long serialVersionUID = -8806743815996713206L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedMap sm; @@ -2149,7 +2154,7 @@ public NavigableSet navigableKeySet() new EmptyNavigableMap<>(); /** - * The instance we wrap and protect. + * @serial The instance we wrap and protect. */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableMap nm; @@ -2283,8 +2288,10 @@ static class SynchronizedCollection implements Collection, Serializable { @java.io.Serial private static final long serialVersionUID = 3053995032091335093L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Collection c; // Backing Collection + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Object mutex; // Object on which to synchronize @@ -2487,6 +2494,7 @@ static class SynchronizedSortedSet @java.io.Serial private static final long serialVersionUID = 8695801310862127406L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedSet ss; @@ -2583,6 +2591,7 @@ static class SynchronizedNavigableSet @java.io.Serial private static final long serialVersionUID = -5505529816273629798L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableSet ns; @@ -2694,6 +2703,7 @@ static class SynchronizedList @java.io.Serial private static final long serialVersionUID = -7754090372962971524L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final List list; @@ -2862,8 +2872,10 @@ private static class SynchronizedMap @java.io.Serial private static final long serialVersionUID = 1978198479659022715L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Map m; // Backing Map + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Object mutex; // Object on which to synchronize @@ -3061,6 +3073,7 @@ static class SynchronizedSortedMap @java.io.Serial private static final long serialVersionUID = -8798146769416483793L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedMap sm; @@ -3165,6 +3178,7 @@ static class SynchronizedNavigableMap @java.io.Serial private static final long serialVersionUID = 699392247599746807L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableMap nm; @@ -3345,8 +3359,10 @@ static class CheckedCollection implements Collection, Serializable { @java.io.Serial private static final long serialVersionUID = 1578914078182001775L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Collection c; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Class type; @@ -3403,6 +3419,7 @@ public void forEachRemaining(Consumer action) { public boolean add(E e) { return c.add(typeCheck(e)); } + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private E[] zeroLengthElementArray; // Lazily initialized @@ -3497,6 +3514,7 @@ static class CheckedQueue { @java.io.Serial private static final long serialVersionUID = 1433151992604707767L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Queue queue; @@ -3602,6 +3620,7 @@ static class CheckedSortedSet extends CheckedSet @java.io.Serial private static final long serialVersionUID = 1599911165492914959L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedSet ss; @@ -3667,6 +3686,7 @@ static class CheckedNavigableSet extends CheckedSortedSet @java.io.Serial private static final long serialVersionUID = -5429120189805438922L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableSet ns; @@ -3751,6 +3771,7 @@ static class CheckedList { @java.io.Serial private static final long serialVersionUID = 65247728283967356L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final List list; @@ -3901,10 +3922,13 @@ private static class CheckedMap @java.io.Serial private static final long serialVersionUID = 5742860141034234728L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Map m; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Class keyType; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Class valueType; @@ -4301,6 +4325,7 @@ static class CheckedSortedMap extends CheckedMap @java.io.Serial private static final long serialVersionUID = 1599671320688067438L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final SortedMap sm; @@ -4377,6 +4402,7 @@ static class CheckedNavigableMap extends CheckedSortedMap @java.io.Serial private static final long serialVersionUID = -4852462692372534096L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final NavigableMap nm; @@ -5108,6 +5134,7 @@ private static class SingletonSet @java.io.Serial private static final long serialVersionUID = 3193687207550431679L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final E element; @@ -5163,6 +5190,7 @@ private static class SingletonList @java.io.Serial private static final long serialVersionUID = 3093736618740652951L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final E element; @@ -5233,8 +5261,10 @@ private static class SingletonMap @java.io.Serial private static final long serialVersionUID = -6979724477215052911L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final K k; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final V v; @@ -5373,7 +5403,9 @@ private static class CopiesList @java.io.Serial private static final long serialVersionUID = 2739099268398711800L; + /** @serial */ final int n; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final E element; @@ -5914,6 +5946,7 @@ public static Set newSetFromMap(Map map) { private static class SetFromMap extends AbstractSet implements Set, Serializable { + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final Map m; // The backing map private transient Set s; // Its keySet @@ -6088,6 +6121,7 @@ static class AsLIFOQueue extends AbstractQueue implements Queue, Serializable { @java.io.Serial private static final long serialVersionUID = 1802017725587941708L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Deque q; AsLIFOQueue(Deque q) { this.q = q; } diff --git a/src/java.base/share/classes/java/util/DuplicateFormatFlagsException.java b/src/java.base/share/classes/java/util/DuplicateFormatFlagsException.java index ebeb3d5c44c..e84cd9d52e6 100644 --- a/src/java.base/share/classes/java/util/DuplicateFormatFlagsException.java +++ b/src/java.base/share/classes/java/util/DuplicateFormatFlagsException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ public non-sealed class DuplicateFormatFlagsException extends IllegalFormatExcep @java.io.Serial private static final long serialVersionUID = 18890531L; + /** @serial */ private String flags; /** diff --git a/src/java.base/share/classes/java/util/FormatFlagsConversionMismatchException.java b/src/java.base/share/classes/java/util/FormatFlagsConversionMismatchException.java index cca7b3eb553..77d52c5e2ba 100644 --- a/src/java.base/share/classes/java/util/FormatFlagsConversionMismatchException.java +++ b/src/java.base/share/classes/java/util/FormatFlagsConversionMismatchException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,8 +40,10 @@ public non-sealed class FormatFlagsConversionMismatchException @java.io.Serial private static final long serialVersionUID = 19120414L; + /** @serial */ private String f; + /** @serial */ private char c; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatCodePointException.java b/src/java.base/share/classes/java/util/IllegalFormatCodePointException.java index 2f1803d220e..c928cd0a3d4 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatCodePointException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatCodePointException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,7 @@ public non-sealed class IllegalFormatCodePointException extends IllegalFormatExc @java.io.Serial private static final long serialVersionUID = 19080630L; + /** @serial */ private int c; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatConversionException.java b/src/java.base/share/classes/java/util/IllegalFormatConversionException.java index 67237f63cdf..3f2b4512dc6 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatConversionException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatConversionException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,9 @@ public non-sealed class IllegalFormatConversionException extends IllegalFormatEx @java.io.Serial private static final long serialVersionUID = 17000126L; + /** @serial */ private char c; + /** @serial */ private Class arg; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatFlagsException.java b/src/java.base/share/classes/java/util/IllegalFormatFlagsException.java index 408fa1efa5c..c0770b7153c 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatFlagsException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatFlagsException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ public non-sealed class IllegalFormatFlagsException extends IllegalFormatExcepti @java.io.Serial private static final long serialVersionUID = 790824L; + /** @serial */ private String flags; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatPrecisionException.java b/src/java.base/share/classes/java/util/IllegalFormatPrecisionException.java index 4527953790c..dbfb712683f 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatPrecisionException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatPrecisionException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ public non-sealed class IllegalFormatPrecisionException extends IllegalFormatExc @java.io.Serial private static final long serialVersionUID = 18711008L; + /** @serial */ private int p; /** diff --git a/src/java.base/share/classes/java/util/IllegalFormatWidthException.java b/src/java.base/share/classes/java/util/IllegalFormatWidthException.java index df8d59b9e81..f22bc61a091 100644 --- a/src/java.base/share/classes/java/util/IllegalFormatWidthException.java +++ b/src/java.base/share/classes/java/util/IllegalFormatWidthException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,7 @@ public non-sealed class IllegalFormatWidthException extends IllegalFormatExcepti @java.io.Serial private static final long serialVersionUID = 16660902L; + /** @serial */ private int w; /** diff --git a/src/java.base/share/classes/java/util/IllformedLocaleException.java b/src/java.base/share/classes/java/util/IllformedLocaleException.java index 47febaae018..f4cafe0a943 100644 --- a/src/java.base/share/classes/java/util/IllformedLocaleException.java +++ b/src/java.base/share/classes/java/util/IllformedLocaleException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,7 @@ public class IllformedLocaleException extends RuntimeException { @java.io.Serial private static final long serialVersionUID = -5245986824925681401L; + /** @serial */ private int _errIdx = -1; /** diff --git a/src/java.base/share/classes/java/util/MissingFormatArgumentException.java b/src/java.base/share/classes/java/util/MissingFormatArgumentException.java index 6363566216b..42d15559415 100644 --- a/src/java.base/share/classes/java/util/MissingFormatArgumentException.java +++ b/src/java.base/share/classes/java/util/MissingFormatArgumentException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,7 @@ public non-sealed class MissingFormatArgumentException extends IllegalFormatExce @java.io.Serial private static final long serialVersionUID = 19190115L; + /** @serial */ private String s; /** diff --git a/src/java.base/share/classes/java/util/MissingFormatWidthException.java b/src/java.base/share/classes/java/util/MissingFormatWidthException.java index b553a3876ac..47f787a0c7b 100644 --- a/src/java.base/share/classes/java/util/MissingFormatWidthException.java +++ b/src/java.base/share/classes/java/util/MissingFormatWidthException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ public non-sealed class MissingFormatWidthException extends IllegalFormatExcepti @java.io.Serial private static final long serialVersionUID = 15560123L; + /** @serial */ private String s; /** diff --git a/src/java.base/share/classes/java/util/PriorityQueue.java b/src/java.base/share/classes/java/util/PriorityQueue.java index 332effeb44b..bacce5ef97e 100644 --- a/src/java.base/share/classes/java/util/PriorityQueue.java +++ b/src/java.base/share/classes/java/util/PriorityQueue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -103,12 +103,12 @@ public class PriorityQueue extends AbstractQueue transient Object[] queue; // non-private to simplify nested class access /** - * The number of elements in the priority queue. + * @serial The number of elements in the priority queue. */ int size; /** - * The comparator, or null if priority queue uses elements' + * @serial The comparator, or null if priority queue uses elements' * natural ordering. */ @SuppressWarnings("serial") // Conditionally serializable diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 1e61136bee4..ab565f371a9 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1656,12 +1656,12 @@ abstract static class NavigableSubMap extends AbstractMap @java.io.Serial private static final long serialVersionUID = -2102997345730753016L; /** - * The backing map. + * @serial The backing map. */ final TreeMap m; /** - * Endpoints are represented as triples (fromStart, lo, + * @serial Endpoints are represented as triples (fromStart, lo, * loInclusive) and (toEnd, hi, hiInclusive). If fromStart is * true, then the low (absolute) bound is the start of the * backing map, and the other values are ignored. Otherwise, @@ -1670,9 +1670,12 @@ abstract static class NavigableSubMap extends AbstractMap */ @SuppressWarnings("serial") // Conditionally serializable final K lo; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable final K hi; + /** @serial */ final boolean fromStart, toEnd; + /** @serial */ final boolean loInclusive, hiInclusive; NavigableSubMap(TreeMap m, @@ -2288,6 +2291,7 @@ static final class DescendingSubMap extends NavigableSubMap { super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive); } + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Comparator reverseComparator = Collections.reverseOrder(m.comparator); @@ -2376,9 +2380,12 @@ private class SubMap extends AbstractMap implements SortedMap, java.io.Serializable { @java.io.Serial private static final long serialVersionUID = -6520786458950516097L; + /** @serial */ private boolean fromStart = false, toEnd = false; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private K fromKey; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private K toKey; @java.io.Serial diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java index e334f7263e4..db0dbe28802 100644 --- a/src/java.base/share/classes/java/util/UUID.java +++ b/src/java.base/share/classes/java/util/UUID.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,17 +83,13 @@ public final class UUID implements java.io.Serializable, Comparable { @java.io.Serial private static final long serialVersionUID = -4856846361193249489L; - /* - * The most significant 64 bits of this UUID. - * - * @serial + /** + * @serial The most significant 64 bits of this UUID. */ private final long mostSigBits; - /* - * The least significant 64 bits of this UUID. - * - * @serial + /** + * @serial The least significant 64 bits of this UUID. */ private final long leastSigBits; diff --git a/src/java.base/share/classes/java/util/UnknownFormatConversionException.java b/src/java.base/share/classes/java/util/UnknownFormatConversionException.java index 13d428e0b60..992d9106644 100644 --- a/src/java.base/share/classes/java/util/UnknownFormatConversionException.java +++ b/src/java.base/share/classes/java/util/UnknownFormatConversionException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ public non-sealed class UnknownFormatConversionException extends IllegalFormatEx @java.io.Serial private static final long serialVersionUID = 19060418L; + /** @serial */ private String s; /** diff --git a/src/java.base/share/classes/java/util/UnknownFormatFlagsException.java b/src/java.base/share/classes/java/util/UnknownFormatFlagsException.java index 93eaf85b389..bcd228b7d0f 100644 --- a/src/java.base/share/classes/java/util/UnknownFormatFlagsException.java +++ b/src/java.base/share/classes/java/util/UnknownFormatFlagsException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ public non-sealed class UnknownFormatFlagsException extends IllegalFormatExcepti @java.io.Serial private static final long serialVersionUID = 19370506L; + /** @serial */ private String flags; /** diff --git a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java index b16f3459601..854bf927464 100644 --- a/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/ArrayBlockingQueue.java @@ -100,17 +100,17 @@ public class ArrayBlockingQueue extends AbstractQueue */ private static final long serialVersionUID = -817911632652898426L; - /** The queued items */ + /** @serial The queued items */ @SuppressWarnings("serial") // Conditionally serializable final Object[] items; - /** items index for next take, poll, peek or remove */ + /** @serial items index for next take, poll, peek or remove */ int takeIndex; - /** items index for next put, offer, or add */ + /** @serial items index for next put, offer, or add */ int putIndex; - /** Number of elements in the queue */ + /** @serial Number of elements in the queue */ int count; /* @@ -118,14 +118,14 @@ public class ArrayBlockingQueue extends AbstractQueue * found in any textbook. */ - /** Main lock guarding all access */ + /** @serial Main lock guarding all access */ final ReentrantLock lock; - /** Condition for waiting takes */ + /** @serial Condition for waiting takes */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notEmpty; - /** Condition for waiting puts */ + /** @serial Condition for waiting puts */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notFull; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 53919011c6f..0cabc63f36e 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -4611,6 +4611,7 @@ public final boolean retainAll(Collection c) { public static final class KeySetView extends CollectionView implements Set, java.io.Serializable { private static final long serialVersionUID = 7249069246763182397L; + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final V value; KeySetView(ConcurrentHashMap map, V value) { // non-public diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 6a60a2397ce..bcfdd997102 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -2401,19 +2401,19 @@ static final class SubMap extends AbstractMap implements ConcurrentNavigableMap, Serializable { private static final long serialVersionUID = -7647078645895051609L; - /** Underlying map */ + /** @serial Underlying map */ final ConcurrentSkipListMap m; - /** lower bound key, or null if from start */ + /** @serial lower bound key, or null if from start */ @SuppressWarnings("serial") // Conditionally serializable private final K lo; - /** upper bound key, or null if to end */ + /** @serial upper bound key, or null if to end */ @SuppressWarnings("serial") // Conditionally serializable private final K hi; - /** inclusion flag for lo */ + /** @serial inclusion flag for lo */ private final boolean loInclusive; - /** inclusion flag for hi */ + /** @serial inclusion flag for hi */ private final boolean hiInclusive; - /** direction */ + /** @serial direction */ final boolean isDescending; // Lazily initialized view holders diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 0bcb7978e90..649eaa563c7 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -99,7 +99,7 @@ public class ConcurrentSkipListSet private static final long serialVersionUID = -2479143111061671589L; /** - * The underlying map. Uses Boolean.TRUE as value for each + * @serial The underlying map. Uses Boolean.TRUE as value for each * element. This field is declared final for the sake of thread * safety, which entails some ugliness in clone(). */ diff --git a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java index ab48a44c97a..cef1682b0b1 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java @@ -99,6 +99,7 @@ public class CopyOnWriteArraySet extends AbstractSet implements java.io.Serializable { private static final long serialVersionUID = 5457747651344034263L; + /** @serial */ private final CopyOnWriteArrayList al; /** diff --git a/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java b/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java index 7884a131ffb..3ca7a5ab9c9 100644 --- a/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java +++ b/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java @@ -427,9 +427,9 @@ public abstract class CountedCompleter extends ForkJoinTask { private static final long serialVersionUID = 5232453752276485070L; - /** This task's completer, or null if none */ + /** @serial This task's completer, or null if none */ final CountedCompleter completer; - /** The number of pending tasks until completion */ + /** @serial The number of pending tasks until completion */ volatile int pending; /** diff --git a/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java b/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java index 7c1e974aafa..6062a0f6455 100644 --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java @@ -278,6 +278,7 @@ final boolean casNext(Aux c, Aux v) { // used only in cancellation static final int UNCOMPENSATE = 1 << 16; // helpJoin sentinel // Fields + /** @serial */ volatile int status; // accessed directly by pool and workers private transient volatile Aux aux; // either waiters or thrown Exception diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java index 7b6523021dc..b22786a09f6 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingDeque.java @@ -152,17 +152,17 @@ static final class Node { /** Number of items in the deque */ private transient int count; - /** Maximum number of items in the deque */ + /** @serial Maximum number of items in the deque */ private final int capacity; - /** Main lock guarding all access */ + /** @serial Main lock guarding all access */ final ReentrantLock lock = new ReentrantLock(); - /** Condition for waiting takes */ + /** @serial Condition for waiting takes */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notEmpty = lock.newCondition(); - /** Condition for waiting puts */ + /** @serial Condition for waiting puts */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notFull = lock.newCondition(); diff --git a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java index a67be9a987d..4f627d0ff5e 100644 --- a/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/LinkedBlockingQueue.java @@ -134,10 +134,10 @@ static class Node { Node(E x) { item = x; } } - /** The capacity bound, or Integer.MAX_VALUE if none */ + /** @serial The capacity bound, or Integer.MAX_VALUE if none */ private final int capacity; - /** Current number of elements */ + /** @serial Current number of elements */ private final AtomicInteger count = new AtomicInteger(); /** @@ -152,17 +152,17 @@ static class Node { */ private transient Node last; - /** Lock held by take, poll, etc */ + /** @serial Lock held by take, poll, etc */ private final ReentrantLock takeLock = new ReentrantLock(); - /** Wait queue for waiting takes */ + /** @serial Wait queue for waiting takes */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notEmpty = takeLock.newCondition(); - /** Lock held by put, offer, etc */ + /** @serial Lock held by put, offer, etc */ private final ReentrantLock putLock = new ReentrantLock(); - /** Wait queue for waiting puts */ + /** @serial Wait queue for waiting puts */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notFull = putLock.newCondition(); diff --git a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java index f51e356736d..ebaecaa525d 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -160,12 +160,12 @@ public class PriorityBlockingQueue extends AbstractQueue private transient Comparator comparator; /** - * Lock used for all public operations. + * @serial Lock used for all public operations. */ private final ReentrantLock lock = new ReentrantLock(); /** - * Condition for blocking when empty. + * @serial Condition for blocking when empty. */ @SuppressWarnings("serial") // Classes implementing Condition may be serializable. private final Condition notEmpty = lock.newCondition(); @@ -176,7 +176,7 @@ public class PriorityBlockingQueue extends AbstractQueue private transient volatile int allocationSpinLock; /** - * A plain PriorityQueue used only for serialization, + * @serial A plain PriorityQueue used only for serialization, * to maintain compatibility with previous versions * of this class. Non-null only during serialization/deserialization. */ diff --git a/src/java.base/share/classes/java/util/concurrent/RecursiveTask.java b/src/java.base/share/classes/java/util/concurrent/RecursiveTask.java index e143760bbc7..4760234c25e 100644 --- a/src/java.base/share/classes/java/util/concurrent/RecursiveTask.java +++ b/src/java.base/share/classes/java/util/concurrent/RecursiveTask.java @@ -84,7 +84,7 @@ public abstract class RecursiveTask extends ForkJoinTask { public RecursiveTask() {} /** - * The result of the computation. + * @serial The result of the computation. */ @SuppressWarnings("serial") // Conditionally serializable V result; diff --git a/src/java.base/share/classes/java/util/concurrent/Semaphore.java b/src/java.base/share/classes/java/util/concurrent/Semaphore.java index 5c299659d6a..0e7a9ccc0b3 100644 --- a/src/java.base/share/classes/java/util/concurrent/Semaphore.java +++ b/src/java.base/share/classes/java/util/concurrent/Semaphore.java @@ -161,7 +161,7 @@ */ public class Semaphore implements java.io.Serializable { private static final long serialVersionUID = -3222578661600680210L; - /** All mechanics via AbstractQueuedSynchronizer subclass */ + /** @serial All mechanics via AbstractQueuedSynchronizer subclass */ private final Sync sync; /** diff --git a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java index f5a2ce4d9b4..49efe5d5c2c 100644 --- a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java @@ -555,8 +555,11 @@ static class LifoWaitQueue extends WaitQueue { static class FifoWaitQueue extends WaitQueue { private static final long serialVersionUID = -3623113410248163686L; } + /** @serial */ private ReentrantLock qlock; + /** @serial */ private WaitQueue waitingProducers; + /** @serial */ private WaitQueue waitingConsumers; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java index fb171e9c1d9..0cae4266b42 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java @@ -55,6 +55,7 @@ public class AtomicBoolean implements java.io.Serializable { private static final VarHandle VALUE = MhUtil.findVarHandle( MethodHandles.lookup(), "value", int.class); + /** @serial */ private volatile int value; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java index 4ebd758ccc7..90b4791f05a 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java @@ -63,6 +63,7 @@ public class AtomicInteger extends Number implements java.io.Serializable { private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value"); + /** @serial */ private volatile int value; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java index 7e253ead335..3757f30372f 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java @@ -51,6 +51,7 @@ public class AtomicIntegerArray implements java.io.Serializable { private static final long serialVersionUID = 2862133569453604235L; private static final VarHandle AA = MethodHandles.arrayElementVarHandle(int[].class); + /** @serial */ private final int[] array; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java index d0e50b0fda8..81c60305a2a 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java @@ -63,6 +63,7 @@ public class AtomicLong extends Number implements java.io.Serializable { private static final long VALUE = U.objectFieldOffset(AtomicLong.class, "value"); + /** @serial */ private volatile long value; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java index 2145c795799..1486b309640 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java @@ -51,6 +51,7 @@ public class AtomicLongArray implements java.io.Serializable { private static final long serialVersionUID = -2308431214976778248L; private static final VarHandle AA = MethodHandles.arrayElementVarHandle(long[].class); + /** @serial */ private final long[] array; /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java index 1d7268609d7..27df942134c 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java @@ -55,6 +55,7 @@ public class AtomicReference implements java.io.Serializable { private static final VarHandle VALUE = MhUtil.findVarHandle( MethodHandles.lookup(), "value", Object.class); + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private volatile V value; diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java index dbec6b81dd9..ff4e9fa7355 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java @@ -55,6 +55,7 @@ public class AtomicReferenceArray implements java.io.Serializable { private static final long serialVersionUID = -6209656149925076980L; private static final VarHandle AA = MethodHandles.arrayElementVarHandle(Object[].class); + /** @serial */ @SuppressWarnings("serial") // Conditionally serializable private final Object[] array; // must have exact type Object[] diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java b/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java index eb837a0fd29..47da669acce 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java @@ -84,8 +84,10 @@ public class DoubleAccumulator extends Striped64 implements Serializable { private static final long serialVersionUID = 7249069246863182397L; + /** @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable private final DoubleBinaryOperator function; + /** @serial */ private final long identity; // use long representation /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java b/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java index 0d48a686cf2..20e69a5f0ce 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java @@ -82,8 +82,10 @@ public class LongAccumulator extends Striped64 implements Serializable { private static final long serialVersionUID = 7249069246863182397L; + /** @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable private final LongBinaryOperator function; + /** @serial */ private final long identity; /** diff --git a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java index 95ac1b2e46f..bdb81f3cb60 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java @@ -152,7 +152,7 @@ public final boolean block() { private transient volatile Node tail; /** - * The synchronization state. + * @serial The synchronization state. */ private volatile long state; diff --git a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java index 6794bab3110..5d899ffb0c5 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java @@ -532,7 +532,7 @@ public final boolean block() { private transient volatile Node tail; /** - * The synchronization state. + * @serial The synchronization state. */ private volatile int state; diff --git a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java index 3378ce3983a..d0ad4cae428 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java @@ -108,7 +108,7 @@ */ public class ReentrantLock implements Lock, java.io.Serializable { private static final long serialVersionUID = 7373984872572414699L; - /** Synchronizer providing all implementation mechanics */ + /** @serial Synchronizer providing all implementation mechanics */ private final Sync sync; /** diff --git a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java index 517708e70f3..cc9b75a7e37 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java @@ -217,11 +217,11 @@ public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable { private static final long serialVersionUID = -6992448646407690164L; - /** Inner class providing readlock */ + /** @serial Inner class providing readlock */ private final ReentrantReadWriteLock.ReadLock readerLock; - /** Inner class providing writelock */ + /** @serial Inner class providing writelock */ private final ReentrantReadWriteLock.WriteLock writerLock; - /** Performs all synchronization mechanics */ + /** @serial Performs all synchronization mechanics */ final Sync sync; /** @@ -713,6 +713,7 @@ final boolean readerShouldBlock() { */ public static class ReadLock implements Lock, java.io.Serializable { private static final long serialVersionUID = -5992448646407690164L; + /** @serial */ private final Sync sync; /** @@ -927,6 +928,7 @@ public String toString() { */ public static class WriteLock implements Lock, java.io.Serializable { private static final long serialVersionUID = -4992448646407690164L; + /** @serial */ private final Sync sync; /** diff --git a/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java b/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java index 2b5da62f5bd..578a97754df 100644 --- a/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java +++ b/src/java.base/share/classes/java/util/regex/PatternSyntaxException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,8 +38,11 @@ public class PatternSyntaxException @java.io.Serial private static final long serialVersionUID = -3864639126226059218L; + /** @serial */ private final String desc; + /** @serial */ private final String pattern; + /** @serial */ private final int index; /** From 4a082c8930ad63d172f0fcdc215903a7d942433e Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Thu, 9 Jan 2025 12:02:25 +0000 Subject: [PATCH 11/25] 8346460: NotifyFramePop should return JVMTI_ERROR_DUPLICATE Reviewed-by: cjplummer, amenkov --- .../MethodExitTest/libMethodExitTest.cpp | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/jvmti/vthread/MethodExitTest/libMethodExitTest.cpp b/test/hotspot/jtreg/serviceability/jvmti/vthread/MethodExitTest/libMethodExitTest.cpp index b7077b10c81..f5e2b267a9f 100644 --- a/test/hotspot/jtreg/serviceability/jvmti/vthread/MethodExitTest/libMethodExitTest.cpp +++ b/test/hotspot/jtreg/serviceability/jvmti/vthread/MethodExitTest/libMethodExitTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -452,13 +452,25 @@ VirtualThreadMount(jvmtiEnv *jvmti, ...) { mname = get_method_name(jvmti, jni, method); cname = get_method_class_name(jvmti, jni, method); + print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadMount", ++vthread_mounted_count); + LOG("\nHit #%d: VirtualThreadMount #%d: enabling FramePop for method: %s::%s on virtual thread: %p\n", - brkptBreakpointHit, ++vthread_mounted_count, cname, mname, (void*)thread); + brkptBreakpointHit, vthread_mounted_count, cname, mname, (void*)thread); err = jvmti->NotifyFramePop(thread, 0); check_jvmti_status(jni, err, "VirtualThreadMount: error in JVMTI NotifyFramePop"); - print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadMount", vthread_mounted_count); + LOG("\nHit #%d: VirtualThreadMount #%d: enabling duplicated FramePop for method: %s::%s on virtual thread: %p\n", + brkptBreakpointHit, vthread_mounted_count, cname, mname, (void*)thread); + + err = jvmti->NotifyFramePop(thread, 0); + if (err == JVMTI_ERROR_DUPLICATE) { + LOG("NotifyFramePop at VirtualThreadUnmount event returned expected JVMTI_ERROR_DUPLICATE\n"); + } else { + LOG("Failed: NotifyFramePop at VirtualThreadUnmount returned %s(%d) instead of expected JVMTI_ERROR_DUPLICATE\n", + TranslateError(err), err); + jni->FatalError("NotifyFramePop error: expected error code JVMTI_ERROR_DUPLICATE"); + } // Test SetThreadLocalStorage for virtual thread. err = jvmti->SetThreadLocalStorage(thread, tls_data2); @@ -497,13 +509,7 @@ VirtualThreadUnmount(jvmtiEnv *jvmti, ...) { mname = get_method_name(jvmti, jni, method); cname = get_method_class_name(jvmti, jni, method); - LOG("\nHit #%d: VirtualThreadUnmount #%d: enabling FramePop for method: %s::%s on virtual thread: %p\n", - brkptBreakpointHit, ++vthread_unmounted_count, cname, mname, (void*)thread); - - err = jvmti->NotifyFramePop(thread, 0); - check_jvmti_status(jni, err, "VirtualThreadUnmount: error in JVMTI NotifyFramePop"); - - print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadUnmount", vthread_unmounted_count); + print_frame_event_info(jvmti, jni, thread, method, "VirtualThreadUnmount", ++vthread_unmounted_count); deallocate(jvmti, jni, (void*)mname); deallocate(jvmti, jni, (void*)cname); From 972c881bfa95f104572ac0acc3acb8e2f8892df2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Nordstr=C3=B6m?= Date: Thu, 9 Jan 2025 12:41:52 +0000 Subject: [PATCH 12/25] 8345782: Refining the cases that libjsig deprecation warning is issued Reviewed-by: dholmes, kevinw --- src/java.base/unix/native/libjsig/jsig.c | 23 ++++-- test/hotspot/jtreg/runtime/signal/README | 5 +- .../jtreg/runtime/signal/SigTestDriver.java | 72 +++++++++++++++---- 3 files changed, 82 insertions(+), 18 deletions(-) diff --git a/src/java.base/unix/native/libjsig/jsig.c b/src/java.base/unix/native/libjsig/jsig.c index ebb4d698946..5dfc56208c1 100644 --- a/src/java.base/unix/native/libjsig/jsig.c +++ b/src/java.base/unix/native/libjsig/jsig.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -47,6 +47,7 @@ #define MAX_SIGNALS NSIG static struct sigaction sact[MAX_SIGNALS]; /* saved signal handlers */ +static bool deprecated_usage[MAX_SIGNALS]; /* usage of signal/sigset */ static sigset_t jvmsigs; /* Signals used by jvm. */ @@ -69,6 +70,7 @@ static sigaction_t os_sigaction = 0; /* os's version of sigaction() */ static bool jvm_signal_installing = false; static bool jvm_signal_installed = false; +static bool warning_printed = false; static void signal_lock() { @@ -89,15 +91,20 @@ static void signal_unlock() { pthread_mutex_unlock(&mutex); } +static void print_deprecation_warning() { + if (!warning_printed) { + warning_printed = true; + fprintf(stderr, HOTSPOT_VM_DISTRO " VM warning: the use of signal() and sigset() " + "for signal chaining was deprecated in version 16.0 and will " + "be removed in a future release. Use sigaction() instead.\n"); + } +} + static sa_handler_t call_os_signal(int sig, sa_handler_t disp, bool is_sigset) { sa_handler_t res; if (os_signal == NULL) { - // Deprecation warning first time through - fprintf(stderr, HOTSPOT_VM_DISTRO " VM warning: the use of signal() and sigset() " - "for signal chaining was deprecated in version 16.0 and will " - "be removed in a future release. Use sigaction() instead.\n"); if (!is_sigset) { os_signal = (signal_function_t)dlsym(RTLD_NEXT, "signal"); } else { @@ -140,8 +147,11 @@ static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) { signal_lock(); + deprecated_usage[sig] = true; + sigused = sigismember(&jvmsigs, sig); if (jvm_signal_installed && sigused) { + print_deprecation_warning(); /* jvm has installed its signal handler for this signal. */ /* Save the handler. Don't really install it. */ if (is_sigset) { @@ -250,6 +260,9 @@ JNIEXPORT int sigaction(int sig, const struct sigaction *act, struct sigaction * * within the JVM_begin_signal_setting-JVM_end_signal_setting-window. There can be any number of non-modifying * calls, but they will only return the expected preexisting handler if executed before the modifying call. */ + if (deprecated_usage[sig] == true) { + print_deprecation_warning(); + } res = call_os_sigaction(sig, act, &oldAct); if (res == 0) { if (act != NULL) { diff --git a/test/hotspot/jtreg/runtime/signal/README b/test/hotspot/jtreg/runtime/signal/README index 7109a0bed5b..d051bbd0ed0 100644 --- a/test/hotspot/jtreg/runtime/signal/README +++ b/test/hotspot/jtreg/runtime/signal/README @@ -1,4 +1,4 @@ -Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,9 @@ Also 2 different ways of setting signal handlers are tested: sigaction, sigset. For 'postpre' and 'postpro' libjsig.so is used to chain signal handlers behind VM installed ones. +When libjsig.so is used, the warning for deprecated usage of signal/sigset is checked. For this +purpose, all scenarios are also run once with libjsig preloaded. + => Current tests cover the following cases (don't count 'nojvm' scenario): 1. Support for pre-installed signal handlers when the HotSpot VM is created. 2. Support for signal handler installation after the HotSpot VM is created inside JNI code diff --git a/test/hotspot/jtreg/runtime/signal/SigTestDriver.java b/test/hotspot/jtreg/runtime/signal/SigTestDriver.java index f2b37af1c39..58c8d40f09c 100644 --- a/test/hotspot/jtreg/runtime/signal/SigTestDriver.java +++ b/test/hotspot/jtreg/runtime/signal/SigTestDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -91,12 +91,16 @@ public static void main(String[] args) { .subList(1, args.length); cmd.addAll(argList); + String failureMessage = null; boolean passed = true; for (String mode : new String[] {"sigset", "sigaction"}) { - for (String scenario : new String[] {"nojvm", "prepre", "prepost", "postpre", "postpost"}) { + // Scenarios postpre and postpost requires libjsig. + // The other scenarios are run with libjsig to validate the deprecation warning. + for (String scenario : new String[] {"nojvm", "prepre", "prepost", "postpre#libjsig", "postpost#libjsig", + "nojvm#libjsig", "prepre#libjsig", "prepost#libjsig", }) { cmd.set(modeIdx, mode); - cmd.set(scenarioIdx, scenario); + cmd.set(scenarioIdx, scenario.replace("#libjsig", "")); System.out.printf("START TESTING: SIGNAL = %s, MODE = %s, SCENARIO=%s%n", signame, mode, scenario); System.out.printf("Do execute: %s%n", cmd.toString()); @@ -105,12 +109,10 @@ public static void main(String[] args) { (x, y) -> y + File.pathSeparator + x); pb.environment().put("CLASSPATH", Utils.TEST_CLASS_PATH); - switch (scenario) { - case "postpre": - case "postpost": { - pb.environment().merge("LD_PRELOAD", libjsig().toString(), - (x, y) -> y + File.pathSeparator + x); - } + boolean useLibjsig = scenario.endsWith("#libjsig"); + if (useLibjsig) { + pb.environment().merge("LD_PRELOAD", libjsig().toString(), + (x, y) -> y + File.pathSeparator + x); } try { @@ -118,11 +120,35 @@ public static void main(String[] args) { oa.reportDiagnosticSummary(); int exitCode = oa.getExitValue(); if (exitCode == 0) { - System.out.println("PASSED with exit code 0"); + // Skip deprecation warning check on MacOSX (see JDK-8346381) + if (useLibjsig && !Platform.isOSX()) { + // verify that deprecation warning for sigset/signal is printed + // only in the correct scenarios + boolean deprecatedSigFunctionUsed = mode.equals("sigset"); + boolean jvmInvolved = !scenario.contains("nojvm"); + boolean warningPrinted = oa.contains("VM warning"); + boolean sigUsedByJVM = sigIsUsedByJVM(signame); + if (deprecatedSigFunctionUsed && jvmInvolved && sigUsedByJVM) { + if (!warningPrinted) { + failureMessage = "FAILED: Missing deprecation warning for mode " + mode + + ", scenario: "+ scenario + ", signal " + signame; + passed = false; + } + } else if (warningPrinted) { + failureMessage = "FAILED: Deprecation warning shouldn't be printed for mode " + mode + + ", scenario: "+ scenario + ", signal " + signame; + passed = false; + } + } else { + System.out.println("PASSED with exit code 0"); + } } else { - System.out.println("FAILED with exit code " + exitCode); + failureMessage = "FAILED with exit code " + exitCode; passed = false; } + if (!passed) { + System.out.println(failureMessage); + } } catch (Exception e) { throw new Error("execution failed", e); } @@ -130,7 +156,7 @@ public static void main(String[] args) { } if (!passed) { - throw new Error("test failed"); + throw new Error(failureMessage != null ? failureMessage : "test failed"); } } @@ -146,4 +172,26 @@ private static List vmargs() { private static Path libjsig() { return Platform.jvmLibDir().resolve(Platform.buildSharedLibraryName("jsig")); } + + /** + * Return true for the chainable signals that are used by the JVM. + * See src/hotspot/os/posix/signals_posix.cpp + * @param signame + * @return true if signal is used by JVM, false otherwise + */ + private static boolean sigIsUsedByJVM(String signame) { + switch(signame) { + case "SIGSEGV": + case "SIGPIPE": + case "SIGBUS": + case "SIGILL": + case "SIGFPE": + case "SIGXFSZ": + return true; + case "SIGTRAP": + return Platform.isPPC(); + default: + return false; + } + } } From e35e294265fb39600b2cc807bfaa116adcc7bbff Mon Sep 17 00:00:00 2001 From: Andrey Turbanov Date: Thu, 9 Jan 2025 12:47:47 +0000 Subject: [PATCH 13/25] 8346036: Unnecessary Hashtable usage in javax.swing.text.html.parser.Entity Reviewed-by: aivanov, azvegint --- .../javax/swing/text/html/parser/Entity.java | 41 +++++++------------ 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/text/html/parser/Entity.java b/src/java.desktop/share/classes/javax/swing/text/html/parser/Entity.java index 8631a6897a7..0b2a9b013af 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/parser/Entity.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/parser/Entity.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,7 @@ package javax.swing.text.html.parser; -import java.util.Hashtable; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.CharArrayReader; -import java.net.URL; +import java.util.Map; /** * An entity is described in a DTD using the ENTITY construct. @@ -40,8 +34,7 @@ * @see DTD * @author Arthur van Hoff */ -public final -class Entity implements DTDConstants { +public final class Entity implements DTDConstants { /** * The name of the entity. */ @@ -117,20 +110,17 @@ public String getString() { return new String(data); } - - static Hashtable entityTypes = new Hashtable(); - - static { - entityTypes.put("PUBLIC", Integer.valueOf(PUBLIC)); - entityTypes.put("CDATA", Integer.valueOf(CDATA)); - entityTypes.put("SDATA", Integer.valueOf(SDATA)); - entityTypes.put("PI", Integer.valueOf(PI)); - entityTypes.put("STARTTAG", Integer.valueOf(STARTTAG)); - entityTypes.put("ENDTAG", Integer.valueOf(ENDTAG)); - entityTypes.put("MS", Integer.valueOf(MS)); - entityTypes.put("MD", Integer.valueOf(MD)); - entityTypes.put("SYSTEM", Integer.valueOf(SYSTEM)); - } + private static final Map entityTypes = Map.of( + "PUBLIC", PUBLIC, + "CDATA", CDATA, + "SDATA", SDATA, + "PI", PI, + "STARTTAG", STARTTAG, + "ENDTAG", ENDTAG, + "MS", MS, + "MD", MD, + "SYSTEM", SYSTEM + ); /** * Converts nm string to the corresponding @@ -144,7 +134,6 @@ public String getString() { * to "CDATA", if none exists */ public static int name2type(String nm) { - Integer i = entityTypes.get(nm); - return (i == null) ? CDATA : i.intValue(); + return entityTypes.getOrDefault(nm, CDATA); } } From ef56cf08cf88d0d375dbccbbf9b12a539718c2c7 Mon Sep 17 00:00:00 2001 From: Joachim Kern Date: Thu, 9 Jan 2025 14:24:12 +0000 Subject: [PATCH 14/25] 8346880: [aix] java/lang/ProcessHandle/InfoTest.java still fails: "reported cputime less than expected" Reviewed-by: mdoerr, clanger, mbaesken --- .../native/libjava/ProcessHandleImpl_aix.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c b/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c index 3568af24ce4..d2c63d31308 100644 --- a/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c +++ b/src/java.base/aix/native/libjava/ProcessHandleImpl_aix.c @@ -162,7 +162,24 @@ jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray, } pid_t os_getParentPidAndTimings(JNIEnv *env, pid_t pid, jlong *total, jlong *start) { - return unix_getParentPidAndTimings(env, pid, total, start); + pid_t the_pid = pid; + struct procentry64 ProcessBuffer; + + if (getprocs64(&ProcessBuffer, sizeof(ProcessBuffer), NULL, sizeof(struct fdsinfo64), &the_pid, 1) <= 0) { + return -1; + } + + // Validate the pid before returning the info + if (kill(pid, 0) < 0) { + return -1; + } + + *total = ((ProcessBuffer.pi_ru.ru_utime.tv_sec + ProcessBuffer.pi_ru.ru_stime.tv_sec) * 1000000000L) + + ((ProcessBuffer.pi_ru.ru_utime.tv_usec + ProcessBuffer.pi_ru.ru_stime.tv_usec)); + + *start = ProcessBuffer.pi_start * (jlong)1000; + + return (pid_t) ProcessBuffer.pi_ppid; } void os_getCmdlineAndUserInfo(JNIEnv *env, jobject jinfo, pid_t pid) { From 56b99d39cbb8c6e9fd35aca8afcb7d94ef70e4b6 Mon Sep 17 00:00:00 2001 From: Archie Cobbs Date: Thu, 9 Jan 2025 14:46:13 +0000 Subject: [PATCH 15/25] 8347141: Several javac tests compile with an unnecessary -Xlint:-path flag Reviewed-by: vromero, darcy --- test/langtools/tools/javac/6304921/T6304921.java | 2 +- test/langtools/tools/javac/T5048776.java | 4 ++-- test/langtools/tools/javac/T6245591.java | 2 +- test/langtools/tools/javac/T6247324.java | 2 +- test/langtools/tools/javac/processing/TestWarnErrorCount.java | 4 ++-- test/langtools/tools/javac/warnings/DivZero.java | 2 +- test/langtools/tools/javac/warnings/FallThrough.java | 2 +- test/langtools/tools/javac/warnings/Unchecked.java | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/langtools/tools/javac/6304921/T6304921.java b/test/langtools/tools/javac/6304921/T6304921.java index 51967b69033..feaf568ee90 100644 --- a/test/langtools/tools/javac/6304921/T6304921.java +++ b/test/langtools/tools/javac/6304921/T6304921.java @@ -1,7 +1,7 @@ /* * @test (important: no SCCS keywords to affect offsets in golden file.) /nodynamiccopyright/ * @bug 6304921 - * @compile/fail/ref=T6304921.out -XDcompilePolicy=bytodo -XDrawDiagnostics -Xjcov -Xlint:all,-path -Werror T6304921.java + * @compile/fail/ref=T6304921.out -XDcompilePolicy=bytodo -XDrawDiagnostics -Xjcov -Xlint:all -Werror T6304921.java */ import java.util.ArrayList; diff --git a/test/langtools/tools/javac/T5048776.java b/test/langtools/tools/javac/T5048776.java index ff3305a9b34..30795020c5a 100644 --- a/test/langtools/tools/javac/T5048776.java +++ b/test/langtools/tools/javac/T5048776.java @@ -1,8 +1,8 @@ /* * @test /nodynamiccopyright/ * @bug 5048776 - * @compile/ref=T5048776a.out -XDrawDiagnostics T5048776.java - * @compile/ref=T5048776b.out -XDrawDiagnostics -Xlint:all,-path T5048776.java + * @compile/ref=T5048776a.out -XDrawDiagnostics T5048776.java + * @compile/ref=T5048776b.out -XDrawDiagnostics -Xlint:all T5048776.java */ class A1 { void foo(Object[] args) { } diff --git a/test/langtools/tools/javac/T6245591.java b/test/langtools/tools/javac/T6245591.java index 7e51e37eab8..8b190dfcdc1 100644 --- a/test/langtools/tools/javac/T6245591.java +++ b/test/langtools/tools/javac/T6245591.java @@ -1,7 +1,7 @@ /* * @test /nodynamiccopyright/ * @bug 6245591 - * @compile/ref=T6245591.out -XDrawDiagnostics -Xlint:all,-path T6245591.java + * @compile/ref=T6245591.out -XDrawDiagnostics -Xlint:all T6245591.java */ enum Season { /** @deprecated */ diff --git a/test/langtools/tools/javac/T6247324.java b/test/langtools/tools/javac/T6247324.java index ae971350c47..264827d6dc0 100644 --- a/test/langtools/tools/javac/T6247324.java +++ b/test/langtools/tools/javac/T6247324.java @@ -1,7 +1,7 @@ /* * @test /nodynamiccopyright/ * @bug 6247324 - * @compile/fail/ref=T6247324.out -XDrawDiagnostics -Xlint -Xlint:-path T6247324.java + * @compile/fail/ref=T6247324.out -XDrawDiagnostics -Xlint T6247324.java */ class Pair { private X x; diff --git a/test/langtools/tools/javac/processing/TestWarnErrorCount.java b/test/langtools/tools/javac/processing/TestWarnErrorCount.java index 1ea2b803609..957bafdab7f 100644 --- a/test/langtools/tools/javac/processing/TestWarnErrorCount.java +++ b/test/langtools/tools/javac/processing/TestWarnErrorCount.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -161,7 +161,7 @@ void test(ErrorKind ek, WarnKind mwk, WarnKind jwk) { "-d", testDir.getPath(), "-processor", myName, // "-XprintRounds", - "-Xlint:all,-path", + "-Xlint:all", "-AerrKind=" + ek, "-AmsgrWarnKind=" + mwk, "-AjavaWarnKind=" + jwk)); diff --git a/test/langtools/tools/javac/warnings/DivZero.java b/test/langtools/tools/javac/warnings/DivZero.java index 2a965f3fbaf..3df7db166d7 100644 --- a/test/langtools/tools/javac/warnings/DivZero.java +++ b/test/langtools/tools/javac/warnings/DivZero.java @@ -3,7 +3,7 @@ * @bug 4759494 4986256 * @compile/ref=DivZero.noLint.out -XDrawDiagnostics DivZero.java * @compile/ref=DivZero.lint.out -Xlint:divzero -XDrawDiagnostics DivZero.java - * @compile/ref=DivZero.lint.out -Xlint:all,-path -XDrawDiagnostics DivZero.java + * @compile/ref=DivZero.lint.out -Xlint:all -XDrawDiagnostics DivZero.java */ class DivZero diff --git a/test/langtools/tools/javac/warnings/FallThrough.java b/test/langtools/tools/javac/warnings/FallThrough.java index 6e5a5eb8bc9..6185c3e0df9 100644 --- a/test/langtools/tools/javac/warnings/FallThrough.java +++ b/test/langtools/tools/javac/warnings/FallThrough.java @@ -2,7 +2,7 @@ * @test /nodynamiccopyright/ * @bug 4986256 * @compile/ref=FallThrough.noLint.out -XDrawDiagnostics FallThrough.java - * @compile/ref=FallThrough.lintAll.out -Xlint:all,-path -XDrawDiagnostics FallThrough.java + * @compile/ref=FallThrough.lintAll.out -Xlint:all -XDrawDiagnostics FallThrough.java * @compile/ref=FallThrough.lintFallThrough.out -Xlint:fallthrough -XDrawDiagnostics FallThrough.java */ diff --git a/test/langtools/tools/javac/warnings/Unchecked.java b/test/langtools/tools/javac/warnings/Unchecked.java index e64fd760a07..7cd8cbfdfd0 100644 --- a/test/langtools/tools/javac/warnings/Unchecked.java +++ b/test/langtools/tools/javac/warnings/Unchecked.java @@ -3,7 +3,7 @@ * @bug 4986256 * @compile/ref=Unchecked.noLint.out -XDrawDiagnostics Unchecked.java * @compile/ref=Unchecked.lintUnchecked.out -Xlint:unchecked -XDrawDiagnostics Unchecked.java - * @compile/ref=Unchecked.lintAll.out -Xlint:all,-path -XDrawDiagnostics Unchecked.java + * @compile/ref=Unchecked.lintAll.out -Xlint:all -XDrawDiagnostics Unchecked.java */ import java.util.ArrayList; From 6dfa4038c850add90d75d956ecef3316f869bfaa Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Thu, 9 Jan 2025 14:58:12 +0000 Subject: [PATCH 16/25] 8346705: SNI not sent with Java 22+ using java.net.http.HttpClient.Builder#sslParameters Reviewed-by: dfuchs, michaelm --- .../net/http/AbstractAsyncSSLConnection.java | 56 ++++- .../net/httpclient/HttpClientSNITest.java | 214 ++++++++++++++++++ .../test/lib/common/ServerNameMatcher.java | 10 + 3 files changed, 268 insertions(+), 12 deletions(-) create mode 100644 test/jdk/java/net/httpclient/HttpClientSNITest.java diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java b/src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java index 7d583266bd3..20f727a9932 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/AbstractAsyncSSLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package jdk.internal.net.http; import java.net.InetSocketAddress; +import java.net.http.HttpClient; import java.util.Arrays; import java.util.ArrayDeque; import java.util.List; @@ -75,7 +76,7 @@ abstract class AbstractAsyncSSLConnection extends HttpConnection ServerName serverName, int port, String[] alpn) { super(addr, client); - this.sniServerNames = formSNIServerNames(serverName); + this.sniServerNames = formSNIServerNames(serverName, client); SSLContext context = client.theSSLContext(); sslParameters = createSSLParameters(client, this.sniServerNames, alpn); Log.logParams(sslParameters); @@ -102,6 +103,20 @@ private static boolean contains(String[] rr, String target) { return false; } + /** + * Returns the {@link SSLParameters} to be used by the {@link SSLEngine} for this connection. + *

+ * The returned {@code SSLParameters} will have its {@link SNIServerName}s set to the given + * {@code sniServerNames}. If {@code alpn} is non-null then the returned {@code SSLParameters} + * will have its {@linkplain SSLParameters#getApplicationProtocols() application layer protocols} + * set to this value. All other parameters in the returned {@code SSLParameters} will be + * copied over from {@link HttpClient#sslParameters()} of the given {@code client}. + * + * @param client the HttpClient + * @param sniServerNames the SNIServerName(s) + * @param alpn the application layer protocols + * @return the SSLParameters to be set on the SSLEngine used by this connection. + */ private static SSLParameters createSSLParameters(HttpClientImpl client, List sniServerNames, String[] alpn) { @@ -132,22 +147,39 @@ private static SSLParameters createSSLParameters(HttpClientImpl client, return sslParameters; } - private static List formSNIServerNames(final ServerName serverName) { - if (serverName == null) { - return List.of(); - } - if (!serverName.isLiteral()) { - String name = serverName.name(); - if (name != null && name.length() > 0) { + /** + * Returns a list of {@link SNIServerName}s that are expected to be used to + * configure the {@link SSLEngine} used by this connection. + *

+ * The given {@code serverName} is given preference, and if it is not null and + * is not an IP address literal, then the returned list will contain only one + * {@code SNIServerName} formed out of the {@code serverName}. If {@code serverName} + * is null or is an IP address literal then the {@code SNIServerName}(s) + * configured through {@link HttpClient#sslParameters()} will be returned. If none have + * been configured, then an empty list is returned. + * + * @param serverName the {@link ServerName}, typically computed based on the request URI + * @param client the {@code HttpClient} + * @return a list of {@code SNIServerName}s to be used by the {@code SSLEngine} + * of this connection. + */ + private static List formSNIServerNames(final ServerName serverName, + final HttpClientImpl client) { + if (serverName != null && !serverName.isLiteral()) { + final String name = serverName.name(); + if (name != null && !name.isEmpty()) { return List.of(new SNIHostName(name)); } } - return List.of(); + // fallback on any SNIServerName(s) configured through HttpClient.sslParameters() + final SSLParameters clientSSLParams = client.sslParameters(); + final List clientConfigured = clientSSLParams.getServerNames(); + return clientConfigured != null ? clientConfigured : List.of(); } - private static SSLEngine createEngine(SSLContext context, String serverName, int port, + private static SSLEngine createEngine(SSLContext context, String peerHost, int port, SSLParameters sslParameters) { - SSLEngine engine = context.createSSLEngine(serverName, port); + SSLEngine engine = context.createSSLEngine(peerHost, port); engine.setUseClientMode(true); engine.setSSLParameters(sslParameters); diff --git a/test/jdk/java/net/httpclient/HttpClientSNITest.java b/test/jdk/java/net/httpclient/HttpClientSNITest.java new file mode 100644 index 00000000000..1505a216593 --- /dev/null +++ b/test/jdk/java/net/httpclient/HttpClientSNITest.java @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpResponse.BodyHandlers; +import java.util.List; + +import javax.net.ssl.SNIHostName; +import javax.net.ssl.SNIMatcher; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; + +import com.sun.net.httpserver.HttpsConfigurator; +import com.sun.net.httpserver.HttpsParameters; +import com.sun.net.httpserver.HttpsServer; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestExchange; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestHandler; +import jdk.httpclient.test.lib.common.HttpServerAdapters.HttpTestServer; +import jdk.httpclient.test.lib.common.ServerNameMatcher; +import jdk.test.lib.net.SimpleSSLContext; +import jdk.test.lib.net.URIBuilder; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import static java.nio.charset.StandardCharsets.US_ASCII; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/* + * @test + * @bug 8346705 + * @summary verify the behaviour of java.net.http.HttpClient + * when sending a Server Name Indication in the TLS + * connections that it establishes for the requests + * @library /test/lib /test/jdk/java/net/httpclient/lib + * @build jdk.httpclient.test.lib.common.HttpServerAdapters + * jdk.test.lib.net.SimpleSSLContext + * jdk.test.lib.net.URIBuilder + * @run junit HttpClientSNITest + */ +public class HttpClientSNITest { + private static final String RESP_BODY_TEXT = "hello world"; + + private static SSLContext sslContext; + + private static final class Handler implements HttpTestHandler { + + @Override + public void handle(final HttpTestExchange exch) throws IOException { + System.out.println("handling request " + exch.getRequestURI()); + final byte[] respBody = RESP_BODY_TEXT.getBytes(US_ASCII); + exch.sendResponseHeaders(200, respBody.length); + try (final OutputStream os = exch.getResponseBody()) { + os.write(respBody); + } + } + } + + @BeforeAll + static void beforeAll() throws Exception { + sslContext = new SimpleSSLContext().get(); + assertNotNull(sslContext, "could not create a SSLContext"); + } + + /* + * Creates and configures a HTTPS server with a SNIMatcher that + * expects a specific SNI name to be sent by the connection client. + * The test uses a HttpClient to issue a couple of requests with the URI having + * a IP address literal as the host. For one of the request, the HttpClient + * is configured with specific ServerName(s) through HttpClient.sslParameters() + * and for the other request, it isn't. + * The test then verifies that for such requests with a IP address literal as the host, + * the HttpClient sends across the ServerName(s) if any has been configured on the client. + */ + @ParameterizedTest + @ValueSource(booleans = {false, true}) + void testRequestToIPLiteralHost(final boolean sniConfiguredOnClient) throws Exception { + final String expectedSNI = "non-dns-resolvable.foo.bar.localhost"; + final ServerNameMatcher matcher = new ServerNameMatcher(expectedSNI); + final HttpTestServer server = createServer(matcher); + try { + final HttpClient.Builder builder = HttpClient.newBuilder().sslContext(sslContext); + if (sniConfiguredOnClient) { + final SSLParameters clientConfiguredSSLParams = new SSLParameters(); + clientConfiguredSSLParams.setServerNames(List.of(new SNIHostName(expectedSNI))); + builder.sslParameters(clientConfiguredSSLParams); + } + try (final HttpClient client = builder.build()) { + final String ipLiteral = InetAddress.getLoopbackAddress().getHostAddress(); + final URI reqURI = URIBuilder.newBuilder() + .host(ipLiteral) + .port(server.getAddress().getPort()) + .scheme("https") + .path("/") + .build(); + final HttpRequest req = HttpRequest.newBuilder(reqURI).build(); + System.out.println("issuing request " + reqURI); + final HttpResponse resp = client.send(req, BodyHandlers.ofString(US_ASCII)); + assertEquals(200, resp.statusCode(), "unexpected response status code"); + assertEquals(RESP_BODY_TEXT, resp.body(), "unexpected response body"); + if (sniConfiguredOnClient) { + assertTrue(matcher.wasInvoked(), "SNIMatcher wasn't invoked on the server"); + } else { + assertFalse(matcher.wasInvoked(), "SNIMatcher was unexpectedly invoked" + + " on the server"); + } + } + } finally { + System.out.println("stopping server " + server.getAddress()); + server.stop(); + } + } + + /* + * Creates and configures a HTTPS server with a SNIMatcher that + * expects a specific SNI name to be sent by the connection client. + * The test uses a HttpClient to issue a couple of requests with the URI having + * a hostname (i.e. not a IP address literal) as the host. For one of the request, + * the HttpClient is configured with specific ServerName(s) through + * HttpClient.sslParameters() and for the other request, it isn't. + * The test then verifies that for such requests with a hostname + * (i.e. not a IP address literal) in the request URI, + * the HttpClient never sends ServerName(s) that may have been configured on the + * client and instead it sends the hostname (from the request URI) as the ServerName + * for each of the request. + */ + @ParameterizedTest + @ValueSource(booleans = {false, true}) + void testRequestResolvedHostName(final boolean sniConfiguredOnClient) throws Exception { + final String resolvedHostName = InetAddress.getLoopbackAddress().getHostName(); + final String expectedSNI = resolvedHostName; + final ServerNameMatcher matcher = new ServerNameMatcher(expectedSNI); + final HttpTestServer server = createServer(matcher); + try { + final HttpClient.Builder builder = HttpClient.newBuilder().sslContext(sslContext); + if (sniConfiguredOnClient) { + final SSLParameters clientConfiguredSSLParams = new SSLParameters(); + clientConfiguredSSLParams.setServerNames(List.of(new SNIHostName("does-not-matter"))); + builder.sslParameters(clientConfiguredSSLParams); + } + try (final HttpClient client = builder.build()) { + final URI reqURI = URIBuilder.newBuilder() + .host(resolvedHostName) + .port(server.getAddress().getPort()) + .scheme("https") + .path("/") + .build(); + final HttpRequest req = HttpRequest.newBuilder(reqURI).build(); + System.out.println("issuing request " + reqURI); + final HttpResponse resp = client.send(req, BodyHandlers.ofString(US_ASCII)); + assertEquals(200, resp.statusCode(), "unexpected response status code"); + assertEquals(RESP_BODY_TEXT, resp.body(), "unexpected response body"); + assertTrue(matcher.wasInvoked(), "SNIMatcher wasn't invoked on the server"); + } + } finally { + System.out.println("stopping server " + server.getAddress()); + server.stop(); + } + } + + /* + * Creates a HttpsServer configured to use the given SNIMatcher + */ + private static HttpTestServer createServer(final SNIMatcher matcher) throws Exception { + final InetSocketAddress addr = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); + final int backlog = 0; + final HttpsServer httpsServer = HttpsServer.create(addr, backlog); + final HttpsConfigurator configurator = new HttpsConfigurator(sslContext) { + @Override + public void configure(final HttpsParameters params) { + final SSLParameters sslParameters = sslContext.getDefaultSSLParameters(); + // add the SNIMatcher + sslParameters.setSNIMatchers(List.of(matcher)); + params.setSSLParameters(sslParameters); + System.out.println("configured HttpsServer with SNIMatcher: " + matcher); + } + }; + httpsServer.setHttpsConfigurator(configurator); + final HttpTestServer server = HttpTestServer.of(httpsServer); + server.addHandler(new Handler(), "/"); + server.start(); + System.out.println("server started at " + server.getAddress()); + return server; + } +} diff --git a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java index 5e7a5790807..47353927e9c 100644 --- a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/ServerNameMatcher.java @@ -58,6 +58,7 @@ public class ServerNameMatcher extends SNIMatcher { private final Logger debug; private final boolean attemptDNSResolution; private final Set recognizedSNINames; + private volatile boolean invoked; /** * Creates a ServerNameMatcher which recognizes the passed {@code recognizedSNIName} @@ -97,6 +98,7 @@ public ServerNameMatcher(final boolean attemptDNSResolution, */ @Override public boolean matches(final SNIServerName clientRequestedSNI) { + this.invoked = true; Objects.requireNonNull(clientRequestedSNI); if (!SNIHostName.class.isInstance(clientRequestedSNI)) { if (debug.on()) { @@ -128,6 +130,14 @@ public boolean matches(final SNIServerName clientRequestedSNI) { return false; } + /** + * @return true if the {@link #matches(SNIServerName)} method of this SNIMatcher instance + * was invoked at least once, false otherwise. + */ + public boolean wasInvoked() { + return this.invoked; + } + private boolean matchesAfterDNSResolution(final String clientRequestedSNI) { final InetAddress clientRequestedAddr; try { From 2ff1ff3e538e8f0e6abbf69099cd2c5e0c231cfa Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Thu, 9 Jan 2025 15:26:38 +0000 Subject: [PATCH 17/25] 8347171: (dc) java/nio/channels/DatagramChannel/InterruptibleOrNot.java fails with virtual thread factory Reviewed-by: alanb, lmesnik --- .../java/nio/channels/DatagramChannel/InterruptibleOrNot.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java b/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java index 794ede84a92..e6fde147bd9 100644 --- a/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java +++ b/test/jdk/java/nio/channels/DatagramChannel/InterruptibleOrNot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.function.Executable; import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assumptions.*; public class InterruptibleOrNot { // DatagramChannel implementation class @@ -98,6 +99,7 @@ public void testInterruptDuringInterruptibleReceive() throws Exception { */ @Test public void testInterruptBeforeUninterruptibleReceive() throws Exception { + assumeFalse(Thread.currentThread().isVirtual()); try (DatagramChannel dc = boundDatagramChannel(false)) { ByteBuffer buf = ByteBuffer.allocate(100); onReceive(() -> { From dca900ab5ef5db0f510dadc6cc1e6d4c76281d04 Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Thu, 9 Jan 2025 17:34:20 +0000 Subject: [PATCH 18/25] 8283795: Add TLSv1.3 and CNSA 1.0 algorithms to implementation requirements Reviewed-by: jnimeh --- .../classes/java/security/AlgorithmParameters.java | 11 +++++++++-- .../share/classes/java/security/KeyFactory.java | 3 +++ .../classes/java/security/KeyPairGenerator.java | 12 ++++++++---- .../share/classes/java/security/MessageDigest.java | 3 ++- .../share/classes/java/security/Signature.java | 10 +++++++++- src/java.base/share/classes/javax/crypto/Cipher.java | 3 ++- .../share/classes/javax/crypto/KeyAgreement.java | 7 +++++-- .../share/classes/javax/crypto/KeyGenerator.java | 3 ++- .../share/classes/javax/net/ssl/SSLContext.java | 5 +++-- 9 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/java.base/share/classes/java/security/AlgorithmParameters.java b/src/java.base/share/classes/java/security/AlgorithmParameters.java index 1fdb47077cf..7747d642c20 100644 --- a/src/java.base/share/classes/java/security/AlgorithmParameters.java +++ b/src/java.base/share/classes/java/security/AlgorithmParameters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,12 +48,19 @@ * obtained via a call to {@code getEncoded}. * *

Every implementation of the Java platform is required to support the - * following standard {@code AlgorithmParameters} algorithms: + * following standard {@code AlgorithmParameters} algorithms. For the "EC" + * algorithm, implementations must support the curves in parentheses. For the + * "RSASSA-PSS" algorithm, implementations must support the parameters in + * parentheses. *

    *
  • {@code AES}
  • + *
  • {@code ChaCha20-Poly1305}
  • *
  • {@code DESede}
  • *
  • {@code DiffieHellman}
  • *
  • {@code DSA}
  • + *
  • {@code EC} (secp256r1, secp384r1)
  • + *
  • {@code RSASSA-PSS} (MGF1 mask generation function and SHA-256 or SHA-384 + * hash algorithms)
  • *
* These algorithms are described in the diff --git a/src/java.base/share/classes/java/security/KeyFactory.java b/src/java.base/share/classes/java/security/KeyFactory.java index 5a9394d283b..7c51faf6aa2 100644 --- a/src/java.base/share/classes/java/security/KeyFactory.java +++ b/src/java.base/share/classes/java/security/KeyFactory.java @@ -72,7 +72,10 @@ *
    *
  • {@code DiffieHellman}
  • *
  • {@code DSA}
  • + *
  • {@code EC}
  • *
  • {@code RSA}
  • + *
  • {@code RSASSA-PSS}
  • + *
  • {@code X25519}
  • *
* These algorithms are described in the
diff --git a/src/java.base/share/classes/java/security/KeyPairGenerator.java b/src/java.base/share/classes/java/security/KeyPairGenerator.java index 31c3d8d382f..3583248f81e 100644 --- a/src/java.base/share/classes/java/security/KeyPairGenerator.java +++ b/src/java.base/share/classes/java/security/KeyPairGenerator.java @@ -113,12 +113,16 @@ * supply their own implementations of key pair generators. * *

Every implementation of the Java platform is required to support the - * following standard {@code KeyPairGenerator} algorithms and keysizes in - * parentheses: + * following standard {@code KeyPairGenerator} algorithms. For the "EC" + * algorithm, implementations must support the curves in parentheses. For other + * algorithms, implementations must support the key sizes in parentheses. *

    - *
  • {@code DiffieHellman} (1024, 2048, 4096)
  • + *
  • {@code DiffieHellman} (1024, 2048, 3072, 4096)
  • *
  • {@code DSA} (1024, 2048)
  • - *
  • {@code RSA} (1024, 2048, 4096)
  • + *
  • {@code EC} (secp256r1, secp384r1)
  • + *
  • {@code RSA} (1024, 2048, 3072, 4096)
  • + *
  • {@code RSASSA-PSS} (2048, 3072, 4096)
  • + *
  • {@code X25519}
  • *
* These algorithms are described in the
diff --git a/src/java.base/share/classes/java/security/MessageDigest.java b/src/java.base/share/classes/java/security/MessageDigest.java index 46455e184b0..f83c4ed6d3b 100644 --- a/src/java.base/share/classes/java/security/MessageDigest.java +++ b/src/java.base/share/classes/java/security/MessageDigest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,6 +87,7 @@ *
    *
  • {@code SHA-1}
  • *
  • {@code SHA-256}
  • + *
  • {@code SHA-384}
  • *
* These algorithms are described in the
diff --git a/src/java.base/share/classes/java/security/Signature.java b/src/java.base/share/classes/java/security/Signature.java index 482db8d4015..006188aac61 100644 --- a/src/java.base/share/classes/java/security/Signature.java +++ b/src/java.base/share/classes/java/security/Signature.java @@ -100,12 +100,20 @@ * supply their own implementations of digital signature algorithms. * *

Every implementation of the Java platform is required to support the - * following standard {@code Signature} algorithms: + * following standard {@code Signature} algorithms. For the "RSASSA-PSS" + * algorithm, implementations must support the parameters in parentheses. For + * the "SHA256withECDSA" and "SHA384withECDSA" algorithms, implementations must + * support the curves in parentheses. *

    + *
  • {@code RSASSA-PSS} (MGF1 mask generation function and SHA-256 or SHA-384 + * hash algorithms)
  • *
  • {@code SHA1withDSA}
  • *
  • {@code SHA256withDSA}
  • + *
  • {@code SHA256withECDSA} (secp256r1)
  • + *
  • {@code SHA384withECDSA} (secp384r1)
  • *
  • {@code SHA1withRSA}
  • *
  • {@code SHA256withRSA}
  • + *
  • {@code SHA384withRSA}
  • *
* These algorithms are described in the
diff --git a/src/java.base/share/classes/javax/crypto/Cipher.java b/src/java.base/share/classes/javax/crypto/Cipher.java index 2cfdcf55823..8187f863b5c 100644 --- a/src/java.base/share/classes/javax/crypto/Cipher.java +++ b/src/java.base/share/classes/javax/crypto/Cipher.java @@ -148,7 +148,8 @@ *
  • {@code AES/CBC/PKCS5Padding} (128)
  • *
  • {@code AES/ECB/NoPadding} (128)
  • *
  • {@code AES/ECB/PKCS5Padding} (128)
  • - *
  • {@code AES/GCM/NoPadding} (128)
  • + *
  • {@code AES/GCM/NoPadding} (128, 256)
  • + *
  • {@code ChaCha20-Poly1305}
  • *
  • {@code DESede/CBC/NoPadding} (168)
  • *
  • {@code DESede/CBC/PKCS5Padding} (168)
  • *
  • {@code DESede/ECB/NoPadding} (168)
  • diff --git a/src/java.base/share/classes/javax/crypto/KeyAgreement.java b/src/java.base/share/classes/javax/crypto/KeyAgreement.java index 8a055b6d809..5e2ceb185aa 100644 --- a/src/java.base/share/classes/javax/crypto/KeyAgreement.java +++ b/src/java.base/share/classes/javax/crypto/KeyAgreement.java @@ -57,11 +57,14 @@ * specific or as specified by the standard key agreement algorithm. * *

    Every implementation of the Java platform is required to support the - * following standard {@code KeyAgreement} algorithm: + * following standard {@code KeyAgreement} algorithms. For the "ECDH" + * algorithm, implementations must support the curves in parentheses. *

      *
    • {@code DiffieHellman}
    • + *
    • {@code ECDH} (secp256r1, secp384r1)
    • + *
    • {@code X25519}
    • *
    - * This algorithm is described in the
    * KeyAgreement section of the * Java Security Standard Algorithm Names Specification. diff --git a/src/java.base/share/classes/javax/crypto/KeyGenerator.java b/src/java.base/share/classes/javax/crypto/KeyGenerator.java index 0826bf2adb5..ad112e6ffeb 100644 --- a/src/java.base/share/classes/javax/crypto/KeyGenerator.java +++ b/src/java.base/share/classes/javax/crypto/KeyGenerator.java @@ -96,7 +96,8 @@ * following standard {@code KeyGenerator} algorithms with the keysizes in * parentheses: *
      - *
    • {@code AES} (128)
    • + *
    • {@code AES} (128, 256)
    • + *
    • {@code ChaCha20}
    • *
    • {@code DESede} (168)
    • *
    • {@code HmacSHA1}
    • *
    • {@code HmacSHA256}
    • diff --git a/src/java.base/share/classes/javax/net/ssl/SSLContext.java b/src/java.base/share/classes/javax/net/ssl/SSLContext.java index 0c2087efa88..861c7645b73 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLContext.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLContext.java @@ -39,11 +39,12 @@ * secure random bytes. * *

      Every implementation of the Java platform is required to support the - * following standard {@code SSLContext} protocol: + * following standard {@code SSLContext} protocols: *

        *
      • {@code TLSv1.2}
      • + *
      • {@code TLSv1.3}
      • *
      - * This protocol is described in the * SSLContext section of the * Java Security Standard Algorithm Names Specification. From a7a88cdbc527beac029317869c146e4e5ab5d427 Mon Sep 17 00:00:00 2001 From: Henry Jen Date: Thu, 9 Jan 2025 17:36:15 +0000 Subject: [PATCH 19/25] 8321413: IllegalArgumentException: Code length outside the allowed range while creating a jlink image Reviewed-by: mchung --- .../jdk/tools/jlink/internal/Snippets.java | 464 ++++++++ .../plugins/ModuleDescriptorBuilder.java | 389 +++++++ .../internal/plugins/SystemModulesPlugin.java | 990 ++++-------------- test/jdk/tools/jlink/JLink20000Packages.java | 129 +++ test/jdk/tools/jlink/SnippetsTest.java | 271 +++++ 5 files changed, 1475 insertions(+), 768 deletions(-) create mode 100644 src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Snippets.java create mode 100644 src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ModuleDescriptorBuilder.java create mode 100644 test/jdk/tools/jlink/JLink20000Packages.java create mode 100644 test/jdk/tools/jlink/SnippetsTest.java diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Snippets.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Snippets.java new file mode 100644 index 00000000000..d662e297f9a --- /dev/null +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Snippets.java @@ -0,0 +1,464 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jlink.internal; + +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.CodeBuilder; +import java.lang.constant.ClassDesc; +import java.lang.constant.MethodTypeDesc; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Objects; + +import static java.lang.classfile.ClassFile.ACC_STATIC; +import java.lang.classfile.TypeKind; +import java.lang.constant.ConstantDesc; +import static java.lang.constant.ConstantDescs.CD_Integer; +import static java.lang.constant.ConstantDescs.CD_Object; +import static java.lang.constant.ConstantDescs.CD_Set; +import static java.lang.constant.ConstantDescs.CD_int; +import java.util.function.Function; + +public class Snippets { + /** + * Snippet of bytecodes + */ + @FunctionalInterface + public interface Snippet { + /** + * Emit the bytecode snippet to the CodeBuilder. + * + * @param cob The CodeBuilder + */ + void emit(CodeBuilder cob); + + /** + * Load a constant onto the operand stack. + */ + static Snippet loadConstant(T v) { + return cob -> cob.loadConstant(v); + } + + /** + * Load an enum constant onto the operand stack. + */ + static Snippet loadEnum(Enum e) { + var classDesc = e.getClass().describeConstable().get(); + return cob -> cob.getstatic(classDesc, e.name(), classDesc); + } + + /** + * Load an Integer, boxed int value onto the operand stack. + */ + static Snippet loadInteger(int value) { + return cob -> + cob.loadConstant(value) + .invokestatic(CD_Integer, "valueOf", MethodTypeDesc.of(CD_Integer, CD_int)); + } + + /** + * Build snippets each to process the corresponding element. + * @param elements The elements to be processed + * @param fn The snippet building function for a given element + * @return Snippets + */ + static Snippet[] buildAll(Collection elements, Function fn) { + return elements.stream() + .map(fn) + .toArray(Snippet[]::new); + } + } + + /** + * Describe an operand that can be load onto the operand stack. + * For example, an array of string can be described as a Loadable. + * + * @param classDesc The type of the operand + * @param load The snippet to load the operand onto the operand stack + */ + public record Loadable(ClassDesc classDesc, Snippet load) implements Snippet { + /** + * Generate the bytecode to load the Loadable onto the operand stack. + * @param cob The CodeBuilder to add the bytecode for loading + */ + @Override + public void emit(CodeBuilder cob) { + load.emit(cob); + } + } + + /** + * Build a snippet for an element with a given index. Typically used for elements in a + * collection to identify the specific element. + */ + @FunctionalInterface + public interface IndexedElementSnippetBuilder { + /** + * Build a snippet for the element at the index. + * @param element The element + * @param index The index of the element in the containing collection + * @return A snippet of bytecodes to process the element + */ + Snippet build(T element, int index); + + default Snippet[] buildAll(Collection elements) { + var loadElementSnippets = new ArrayList(elements.size()); + for (var element: elements) { + loadElementSnippets.add(build(element, loadElementSnippets.size())); + } + + assert(loadElementSnippets.size() == elements.size()); + return loadElementSnippets.toArray(Snippet[]::new); + } + } + + /** + * Some basic information about pagination. + * @param total The total count of elements + * @param pageSize the number or elements to be included in a page + */ + public static record PagingContext(int total, int pageSize) { + /** + * If the last page has less elements than given page size. + */ + public boolean isLastPagePartial() { + return (total % pageSize) != 0; + } + + /** + * The number of pages. + */ + public int pageCount() { + var pages = total / pageSize; + return isLastPagePartial() ? pages + 1 : pages; + } + + /** + * The number of elements in the last page. + */ + public int lastPageSize() { + if (total == 0) return 0; + var remaining = total % pageSize; + return remaining == 0 ? pageSize : remaining; + } + } + + /** + * Generate bytecodes for loading a collection of elements, support using pagination to avoid + * overloading the 64k code limit. + */ + public static abstract class CollectionSnippetBuilder { + /** + * Default page size of string array + */ + public static final int STRING_PAGE_SIZE = 8000; + + /** + * Default page size of enum array + */ + public static final int ENUM_PAGE_SIZE = 5000; + + /** + * Good enough for average ~30 bytes per element + */ + public static final int DEFAULT_PAGE_SIZE = 2000; + + /** + * Default threshold based on 15K code size on ~30 bytes per element + */ + protected static final int DEFAULT_THRESHOLD = 512; + + protected ClassDesc elementType; + protected ClassDesc ownerClassDesc; + protected ClassBuilder clb; + + // Default values, disable pagination by default + protected String methodNamePrefix = null; + protected int activatePagingThreshold = -1; + protected int pageSize = DEFAULT_PAGE_SIZE; + + /** + * @param elementType The element type + */ + protected CollectionSnippetBuilder(ClassDesc elementType) { + this.elementType = Objects.requireNonNull(elementType); + } + + /** + * Enable pagination if the count of elements is larger than the given threshold. + * + * @param methodNamePrefix The method name prefix for generated paging helper methods + * @param pageSize The page size + * @param threshold The element count to actiave the pagination + */ + public CollectionSnippetBuilder enablePagination(String methodNamePrefix, int pageSize, int threshold) { + return this.pageSize(pageSize) + .activatePagingThreshold(threshold) + .methodNamePrefix(methodNamePrefix); + } + + /** + * Enable pagination if the count of elements is larger than pageSize or DEFAULT_THRESHOLD + */ + public CollectionSnippetBuilder enablePagination(String methodNamePrefix, int pageSize) { + return enablePagination(methodNamePrefix, pageSize, Math.min(pageSize, DEFAULT_THRESHOLD)); + } + + /** + * Enable pagination if the count of elements is larger than pageSize or DEFAULT_THRESHOLD + * with page size DEFAULT_PAGE_SIZE. + */ + public CollectionSnippetBuilder enablePagination(String methodNamePrefix) { + return enablePagination(methodNamePrefix, DEFAULT_PAGE_SIZE, DEFAULT_THRESHOLD); + } + + /** + * Disable pagination. Generated bytecode will always try to construct the collection inline. + */ + public CollectionSnippetBuilder disablePagination() { + this.activatePagingThreshold = -1; + this.methodNamePrefix = null; + return this; + } + + /** + * Set the threshold of element count to enable pagination. + * + * @param activatePagingThreshold Use pagination methods if the count of elements is larger + * than the given value + */ + public CollectionSnippetBuilder activatePagingThreshold(int activatePagingThreshold) { + if (activatePagingThreshold <= 0) { + throw new IllegalArgumentException(); + } + this.activatePagingThreshold = activatePagingThreshold; + return this; + } + + /** + * Set the owner class host the pagination methods. + * + * @param ownerClassDesc The owner class for the pagination methods + */ + public CollectionSnippetBuilder ownerClassDesc(ClassDesc ownerClassDesc) { + this.ownerClassDesc = Objects.requireNonNull(ownerClassDesc); + return this; + } + + /** + * Set the method name prefix for the pagination methods. + * @param methodNamePrefix The method name prefix. Generated method will have the name of + * this value appended with page number + */ + public CollectionSnippetBuilder methodNamePrefix(String methodNamePrefix) { + this.methodNamePrefix = Objects.requireNonNull(methodNamePrefix); + if (methodNamePrefix.isBlank()) { + throw new IllegalArgumentException(); + } + return this; + } + + /** + * Set the page size. The max page size is STRING_PAGE_SIZE. + * @param pageSize The count of elements per page* + */ + public CollectionSnippetBuilder pageSize(int pageSize) { + // ldc is likely the smallest element snippet + if (pageSize <= 0 || pageSize > STRING_PAGE_SIZE) { + throw new IllegalArgumentException(); + } + + this.pageSize = pageSize; + return this; + } + + /** + * Set the class builder used to generate the pagination methods. + * + * This value must be set if pagination is needed, otherwise the build + * would lead to NullPointerException. + */ + public CollectionSnippetBuilder classBuilder(ClassBuilder clb) { + this.clb = Objects.requireNonNull(clb); + return this; + } + + protected boolean shouldPaginate(int length) { + return methodNamePrefix != null && activatePagingThreshold > 0 && length > activatePagingThreshold; + } + + /** + * Build the Loadable snippet to load the collection of elements onto + * the operand stack. When pagination is enabled and needed as the total + * count of elements is larger than the given threshold, missing + * required field will lead to NullPointerException. + * + * @param loadElementSnippets The array of Snippets used to load individual + * element in the collection. + * @return The Loadable snippet + * @throws NullPointerException + */ + abstract public Loadable build(Snippet[] loadElementSnippets); + } + + /** + * Generate bytecode to load an array of the given referene type onto the operand stack. + * + * The generated code will create an array inline, and then populate the array either inline or + * by invoking the first pagination method if pagination is activated. + * + * If pagination is activated, pagination methods are generated with the given ClassBuilder + * with method name formatted with the methodNamePrefix appended with page numberand. + * Each pagination method will assign value to the corresponding page and chain calling next page. + * + * Effectively as + * methodNamePrefix_0(new T[elements.size()]); + * + * where + * T[] methodNamePrefix_0(T[] ar) { + * ar[0] = elements[0]; + * ar[1] = elements[1]; + * ... + * ar[pageSize-1] = elements[pageSize - 1]; + * methodNamePrefix_1(ar); + * return ar; + * } + * and the last page will stop the chain and can be partial instead of full page size. + */ + public static class ArraySnippetBuilder extends CollectionSnippetBuilder { + final MethodTypeDesc MTD_PageHelper; + final ClassDesc classDesc; + Snippet[] loadElementSnippets; + + public ArraySnippetBuilder(ClassDesc elementType) { + super(elementType); + classDesc = elementType.arrayType(); + MTD_PageHelper = MethodTypeDesc.of(classDesc, classDesc); + } + + protected void fill(CodeBuilder cob, int fromIndex, int toIndex) { + for (var index = fromIndex; index < toIndex; index++) { + cob.dup() // arrayref + .loadConstant(index); + loadElementSnippets[index].emit(cob); // value + cob.aastore(); + } + } + + private void invokePageHelper(CodeBuilder cob) { + // Invoke the first page, which will call next page until fulfilled + cob.loadConstant(loadElementSnippets.length) + .anewarray(elementType) + .invokestatic(ownerClassDesc, methodNamePrefix + "_0", MTD_PageHelper); + } + + private void newArray(CodeBuilder cob) { + cob.loadConstant(loadElementSnippets.length) + .anewarray(elementType); + fill(cob, 0, loadElementSnippets.length); + } + + /** + * Generate helper methods to fill each page + */ + private void setupHelpers() { + Objects.requireNonNull(clb); + Objects.requireNonNull(methodNamePrefix); + Objects.requireNonNull(ownerClassDesc); + var lastPageNo = new PagingContext(loadElementSnippets.length, pageSize).pageCount() - 1; + for (int pageNo = 0; pageNo <= lastPageNo; pageNo++) { + genFillPageHelper(pageNo, pageNo < lastPageNo); + } + } + + // each helper function is T[] methodNamePrefix_{pageNo}(T[]) + // fill the page portion and chain calling to fill next page + private void genFillPageHelper(int pageNo, boolean hasNextPage) { + var fromIndex = pageSize * pageNo; + var toIndex = hasNextPage ? (fromIndex + pageSize) : loadElementSnippets.length; + clb.withMethodBody(methodNamePrefix + "_" + pageNo, + MTD_PageHelper, + ACC_STATIC, + cob -> { + cob.aload(0); // arrayref + fill(cob, fromIndex, toIndex); + if (hasNextPage) { + cob.invokestatic( + ownerClassDesc, + methodNamePrefix + "_" + (pageNo + 1), + MTD_PageHelper); + } + cob.return_(TypeKind.from(classDesc)); + }); + } + + @Override + public Loadable build(Snippet[] loadElementSnippets) { + this.loadElementSnippets = Objects.requireNonNull(loadElementSnippets); + if (shouldPaginate(loadElementSnippets.length)) { + setupHelpers(); + return new Loadable(classDesc, this::invokePageHelper); + } else { + return new Loadable(classDesc, this::newArray); + } + } + } + + /** + * Generate bytecodes to load a set onto the operand stack. + * + * The Set is constructed with Set::of method. When there are more than 2 + * elements in the set, an array is constructed. + */ + public static class SetSnippetBuilder extends ArraySnippetBuilder { + public SetSnippetBuilder(ClassDesc elementType) { + super(elementType); + } + + private void buildTinySet(CodeBuilder cob) { + for (var snippet: loadElementSnippets) { + snippet.emit(cob); + } + var mtdArgs = new ClassDesc[loadElementSnippets.length]; + Arrays.fill(mtdArgs, CD_Object); + cob.invokestatic(CD_Set, "of", MethodTypeDesc.of(CD_Set, mtdArgs), true); + } + + @Override + public Loadable build(Snippet[] loadElementSnippets) { + if (loadElementSnippets.length <= 2) { + this.loadElementSnippets = loadElementSnippets; + return new Loadable(CD_Set, this::buildTinySet); + } else { + var array = super.build(loadElementSnippets); + return new Loadable(CD_Set, cob -> { + array.emit(cob); + cob.invokestatic(CD_Set, "of", MethodTypeDesc.of(CD_Set, CD_Object.arrayType()), true); + }); + } + } + } +} \ No newline at end of file diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ModuleDescriptorBuilder.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ModuleDescriptorBuilder.java new file mode 100644 index 00000000000..dac50c86161 --- /dev/null +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ModuleDescriptorBuilder.java @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.tools.jlink.internal.plugins; + +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.CodeBuilder; +import java.lang.constant.ClassDesc; +import static java.lang.constant.ConstantDescs.*; + +import java.lang.constant.MethodTypeDesc; +import java.lang.module.ModuleDescriptor; +import java.lang.module.ModuleDescriptor.Exports; +import java.lang.module.ModuleDescriptor.Opens; +import java.lang.module.ModuleDescriptor.Provides; +import java.lang.module.ModuleDescriptor.Requires; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import static jdk.tools.jlink.internal.Snippets.*; +import static jdk.tools.jlink.internal.Snippets.CollectionSnippetBuilder.STRING_PAGE_SIZE; + +import jdk.tools.jlink.internal.plugins.SystemModulesPlugin.ModuleInfo; +import jdk.tools.jlink.internal.plugins.SystemModulesPlugin.SystemModulesClassGenerator.DedupSnippets; + +/** + * Build a Snippet to load a ModuleDescriptor onto the operand stack. + */ +class ModuleDescriptorBuilder implements IndexedElementSnippetBuilder { + private static final ClassDesc CD_MODULE_DESCRIPTOR = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor"); + private static final ClassDesc CD_MODULE_BUILDER = + ClassDesc.ofInternalName("jdk/internal/module/Builder"); + + private final DedupSnippets dedupSnippets; + private final ClassDesc ownerClassDesc; + private final ClassBuilder clb; + + ModuleDescriptorBuilder(ClassBuilder clb, DedupSnippets dedupSnippets, ClassDesc ownerClassDesc) { + this.clb = clb; + this.dedupSnippets = dedupSnippets; + this.ownerClassDesc = ownerClassDesc; + } + + @Override + public Snippet build(ModuleInfo moduleInfo, int index) { + return new ModuleDescriptorSnippet(clb, moduleInfo.descriptor(), moduleInfo.packages(), index); + } + + class ModuleDescriptorSnippet implements Snippet { + static final ClassDesc CD_EXPORTS = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Exports"); + static final ClassDesc CD_OPENS = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Opens"); + static final ClassDesc CD_PROVIDES = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Provides"); + static final ClassDesc CD_REQUIRES = + ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Requires"); + + // method signature for static Builder::newExports, newOpens, + // newProvides, newRequires methods + static final MethodTypeDesc MTD_EXPORTS_MODIFIER_SET_STRING_SET = + MethodTypeDesc.of(CD_EXPORTS, CD_Set, CD_String, CD_Set); + static final MethodTypeDesc MTD_EXPORTS_MODIFIER_SET_STRING = + MethodTypeDesc.of(CD_EXPORTS, CD_Set, CD_String); + static final MethodTypeDesc MTD_OPENS_MODIFIER_SET_STRING_SET = + MethodTypeDesc.of(CD_OPENS, CD_Set, CD_String, CD_Set); + static final MethodTypeDesc MTD_OPENS_MODIFIER_SET_STRING = + MethodTypeDesc.of(CD_OPENS, CD_Set, CD_String); + static final MethodTypeDesc MTD_PROVIDES_STRING_LIST = + MethodTypeDesc.of(CD_PROVIDES, CD_String, CD_List); + static final MethodTypeDesc MTD_REQUIRES_SET_STRING = + MethodTypeDesc.of(CD_REQUIRES, CD_Set, CD_String); + static final MethodTypeDesc MTD_REQUIRES_SET_STRING_STRING = + MethodTypeDesc.of(CD_REQUIRES, CD_Set, CD_String, CD_String); + + // method signature for Builder instance methods that + // return this Builder instance + static final MethodTypeDesc MTD_EXPORTS_ARRAY = + MethodTypeDesc.of(CD_MODULE_BUILDER, CD_EXPORTS.arrayType()); + static final MethodTypeDesc MTD_OPENS_ARRAY = + MethodTypeDesc.of(CD_MODULE_BUILDER, CD_OPENS.arrayType()); + static final MethodTypeDesc MTD_PROVIDES_ARRAY = + MethodTypeDesc.of(CD_MODULE_BUILDER, CD_PROVIDES.arrayType()); + static final MethodTypeDesc MTD_REQUIRES_ARRAY = + MethodTypeDesc.of(CD_MODULE_BUILDER, CD_REQUIRES.arrayType()); + static final MethodTypeDesc MTD_SET = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_Set); + static final MethodTypeDesc MTD_STRING = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_String); + static final MethodTypeDesc MTD_BOOLEAN = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_boolean); + static final MethodTypeDesc MTD_void_String = MethodTypeDesc.of(CD_void, CD_String); + static final MethodTypeDesc MTD_ModuleDescriptor_int = MethodTypeDesc.of(CD_MODULE_DESCRIPTOR, CD_int); + static final MethodTypeDesc MTD_List_ObjectArray = MethodTypeDesc.of(CD_List, CD_Object.arrayType()); + + final ModuleDescriptor md; + final int index; + final Snippet requiresArray; + final Snippet exportsArray; + final Snippet opensArray; + final Snippet providesArray; + final Snippet packagesSet; + + ModuleDescriptorSnippet(ClassBuilder clb, ModuleDescriptor md, Set packages, int index) { + if (md.isAutomatic()) { + throw new InternalError("linking automatic module is not supported"); + } + + this.md = md; + this.index = index; + requiresArray = buildRequiresArray(clb); + exportsArray = buildExportsArray(clb); + opensArray = buildOpensArray(clb); + providesArray = buildProvidesArray(clb); + packagesSet = buildPackagesSet(clb, packages); + } + + /* + * Invoke Builder.newRequires(Set mods, String mn, String compiledVersion) + * + * Set mods = ... + * Builder.newRequires(mods, mn, compiledVersion); + */ + Snippet loadRequire(Requires require) { + return cob -> { + dedupSnippets.requiresModifiersSets().get(require.modifiers()).emit(cob); + cob.loadConstant(require.name()); + if (require.compiledVersion().isPresent()) { + cob.loadConstant(require.compiledVersion().get().toString()) + .invokestatic(CD_MODULE_BUILDER, + "newRequires", + MTD_REQUIRES_SET_STRING_STRING); + } else { + cob.invokestatic(CD_MODULE_BUILDER, + "newRequires", + MTD_REQUIRES_SET_STRING); + } + }; + } + + private Snippet buildRequiresArray(ClassBuilder clb) { + return new ArraySnippetBuilder(CD_REQUIRES) + .enablePagination("module" + index + "Requires") + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .build(Snippet.buildAll(sorted(md.requires()), this::loadRequire)); + } + + /* + * Invoke + * Builder.newExports(Set ms, String pn, + * Set targets) + * or + * Builder.newExports(Set ms, String pn) + * + * ms = export.modifiers() + * pn = export.source() + * targets = export.targets() + */ + Snippet loadExports(Exports export) { + return cob -> { + dedupSnippets.exportsModifiersSets().get(export.modifiers()).emit(cob); + cob.loadConstant(export.source()); + var targets = export.targets(); + if (!targets.isEmpty()) { + dedupSnippets.stringSets().get(targets).emit(cob); + cob.invokestatic(CD_MODULE_BUILDER, + "newExports", + MTD_EXPORTS_MODIFIER_SET_STRING_SET); + } else { + cob.invokestatic(CD_MODULE_BUILDER, + "newExports", + MTD_EXPORTS_MODIFIER_SET_STRING); + } + }; + } + + private Snippet buildExportsArray(ClassBuilder clb) { + return new ArraySnippetBuilder(CD_EXPORTS) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Exports") + .build(Snippet.buildAll(sorted(md.exports()), this::loadExports)); + } + + /* + * Invoke + * Builder.newOpens(Set ms, String pn, + * Set targets) + * or + * Builder.newOpens(Set ms, String pn) + * + * ms = open.modifiers() + * pn = open.source() + * targets = open.targets() + * Builder.newOpens(mods, pn, targets); + */ + Snippet loadOpens(Opens open) { + return cob -> { + dedupSnippets.opensModifiersSets().get(open.modifiers()).emit(cob); + cob.loadConstant(open.source()); + var targets = open.targets(); + if (!targets.isEmpty()) { + dedupSnippets.stringSets().get(targets).emit(cob); + cob.invokestatic(CD_MODULE_BUILDER, + "newOpens", + MTD_OPENS_MODIFIER_SET_STRING_SET); + } else { + cob.invokestatic(CD_MODULE_BUILDER, + "newOpens", + MTD_OPENS_MODIFIER_SET_STRING); + } + }; + } + + private Snippet buildOpensArray(ClassBuilder clb) { + return new ArraySnippetBuilder(CD_OPENS) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Opens") + .build(Snippet.buildAll(sorted(md.opens()), this::loadOpens)); + } + + /* + * Invoke Builder.newProvides(String service, List providers) + * + * service = provide.service() + * providers = List.of(new String[] { provide.providers() } + * Builder.newProvides(service, providers); + */ + private Snippet loadProvides(ClassBuilder clb, Provides provide, int offset) { + return cob -> { + var providersArray = new ArraySnippetBuilder(CD_String) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Provider" + offset) + .pageSize(STRING_PAGE_SIZE) + .build(Snippet.buildAll(provide.providers(), Snippet::loadConstant)); + + cob.loadConstant(provide.service()); + providersArray.emit(cob); + cob.invokestatic(CD_List, + "of", + MTD_List_ObjectArray, + true) + .invokestatic(CD_MODULE_BUILDER, + "newProvides", + MTD_PROVIDES_STRING_LIST); + }; + } + + private Snippet buildProvidesArray(ClassBuilder clb) { + IndexedElementSnippetBuilder builder = (e, i) -> loadProvides(clb, e, i); + return new ArraySnippetBuilder(CD_PROVIDES) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Provides") + .build(builder.buildAll(md.provides())); + } + + private Snippet buildPackagesSet(ClassBuilder clb, Collection packages) { + return new SetSnippetBuilder(CD_String) + .classBuilder(clb) + .ownerClassDesc(ownerClassDesc) + .enablePagination("module" + index + "Packages") + .pageSize(STRING_PAGE_SIZE) + .build(Snippet.buildAll(sorted(packages), Snippet::loadConstant)); + } + + @Override + public void emit(CodeBuilder cob) { + // new jdk.internal.module.Builder + cob.new_(CD_MODULE_BUILDER) + .dup() + .loadConstant(md.name()) + .invokespecial(CD_MODULE_BUILDER, + INIT_NAME, + MTD_void_String); + if (md.isOpen()) { + setModuleBit(cob, "open", true); + } + if (md.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC)) { + setModuleBit(cob, "synthetic", true); + } + if (md.modifiers().contains(ModuleDescriptor.Modifier.MANDATED)) { + setModuleBit(cob, "mandated", true); + } + + // requires + requiresArray.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "requires", + MTD_REQUIRES_ARRAY); + + // exports + exportsArray.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "exports", + MTD_EXPORTS_ARRAY); + + // opens + opensArray.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "opens", + MTD_OPENS_ARRAY); + + // uses + dedupSnippets.stringSets().get(md.uses()).emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "uses", + MTD_SET); + + // provides + providesArray.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "provides", + MTD_PROVIDES_ARRAY); + + // all packages + packagesSet.emit(cob); + cob.invokevirtual(CD_MODULE_BUILDER, + "packages", + MTD_SET); + + // version + md.version().ifPresent(v -> setModuleProperty(cob, "version", v.toString())); + + // main class + md.mainClass().ifPresent(cn -> setModuleProperty(cob, "mainClass", cn)); + + cob.loadConstant(md.hashCode()) + .invokevirtual(CD_MODULE_BUILDER, + "build", + MTD_ModuleDescriptor_int); + } + + /* + * Invoke Builder.(boolean value) + */ + void setModuleBit(CodeBuilder cob, String methodName, boolean value) { + cob.loadConstant(value ? 1 : 0) + .invokevirtual(CD_MODULE_BUILDER, + methodName, + MTD_BOOLEAN); + } + + void setModuleProperty(CodeBuilder cob, String methodName, String value) { + cob.loadConstant(value) + .invokevirtual(CD_MODULE_BUILDER, + methodName, + MTD_STRING); + } + } + + /** + * Returns a sorted copy of a collection. + * + * This is useful to ensure a deterministic iteration order. + * + * @return a sorted copy of the given collection. + */ + private static > List sorted(Collection c) { + var l = new ArrayList<>(c); + Collections.sort(l); + return l; + } +} \ No newline at end of file diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java index 1a9404b210d..1c126d7321c 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java @@ -29,7 +29,6 @@ import java.io.IOException; import java.io.InputStream; import java.lang.constant.ClassDesc; -import java.lang.constant.ConstantDesc; import static java.lang.constant.ConstantDescs.*; import java.lang.constant.MethodTypeDesc; import java.lang.module.Configuration; @@ -38,7 +37,6 @@ import java.lang.module.ModuleDescriptor.Opens; import java.lang.module.ModuleDescriptor.Provides; import java.lang.module.ModuleDescriptor.Requires; -import java.lang.module.ModuleDescriptor.Version; import java.lang.module.ModuleFinder; import java.lang.module.ModuleReader; import java.lang.module.ModuleReference; @@ -46,7 +44,6 @@ import java.lang.reflect.ClassFileFormatVersion; import java.net.URI; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.EnumSet; @@ -60,7 +57,6 @@ import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; -import java.util.function.IntSupplier; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -78,15 +74,22 @@ import java.lang.classfile.ClassBuilder; import java.lang.classfile.ClassFile; import java.lang.classfile.TypeKind; -import static java.lang.classfile.ClassFile.*; import java.lang.classfile.CodeBuilder; +import java.nio.file.Files; +import java.nio.file.Path; + import jdk.tools.jlink.internal.ModuleSorter; import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.ResourcePool; import jdk.tools.jlink.plugin.ResourcePoolBuilder; import jdk.tools.jlink.plugin.ResourcePoolEntry; +import static java.lang.classfile.ClassFile.*; +import static jdk.tools.jlink.internal.Snippets.*; +import static jdk.tools.jlink.internal.Snippets.CollectionSnippetBuilder.ENUM_PAGE_SIZE; +import static jdk.tools.jlink.internal.Snippets.CollectionSnippetBuilder.STRING_PAGE_SIZE; + /** * Jlink plugin to reconstitute module descriptors and other attributes for system * modules. The plugin generates implementations of SystemModules to avoid parsing @@ -329,6 +332,17 @@ private String genSystemModulesClass(List moduleInfos, SystemModulesClassGenerator generator = new SystemModulesClassGenerator(className, moduleInfos, moduleDescriptorsPerMethod); byte[] bytes = generator.genClassBytes(cf); + // Diagnosis help, can be removed + if (Boolean.parseBoolean(System.getProperty("jlink.dumpSystemModuleClass", "false"))) { + try { + var filePath = Path.of(className + ".class").toAbsolutePath(); + System.err.println("Write " + filePath.toString()); + Files.createDirectories(filePath.getParent()); + Files.write(filePath, bytes); + } catch (IOException ioe) { + ioe.printStackTrace(System.err); + } + } String rn = "/java.base/" + className + ".class"; ResourcePoolEntry e = ResourcePoolEntry.create(rn, bytes); out.add(e); @@ -513,14 +527,6 @@ byte[] getBytes() throws IOException { static class SystemModulesClassGenerator { private static final ClassDesc CD_MODULE_DESCRIPTOR = ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor"); - private static final ClassDesc CD_MODULE_BUILDER = - ClassDesc.ofInternalName("jdk/internal/module/Builder"); - private static final ClassDesc CD_REQUIRES_MODIFIER = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Requires$Modifier"); - private static final ClassDesc CD_EXPORTS_MODIFIER = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Exports$Modifier"); - private static final ClassDesc CD_OPENS_MODIFIER = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Opens$Modifier"); private static final ClassDesc CD_MODULE_TARGET = ClassDesc.ofInternalName("jdk/internal/module/ModuleTarget"); private static final ClassDesc CD_MODULE_HASHES = @@ -538,16 +544,12 @@ static class SystemModulesClassGenerator { private static final MethodTypeDesc MTD_Map = MethodTypeDesc.of(CD_Map); private static final MethodTypeDesc MTD_MapEntry_Object_Object = MethodTypeDesc.of(CD_Map_Entry, CD_Object, CD_Object); private static final MethodTypeDesc MTD_Map_MapEntryArray = MethodTypeDesc.of(CD_Map, CD_Map_Entry.arrayType()); - private static final MethodTypeDesc MTD_Set_ObjectArray = MethodTypeDesc.of(CD_Set, CD_Object.arrayType()); private static final int MAX_LOCAL_VARS = 256; - private final int MD_VAR = 1; // variable for ModuleDescriptor private final int MT_VAR = 1; // variable for ModuleTarget private final int MH_VAR = 1; // variable for ModuleHashes - private final int DEDUP_LIST_VAR = 2; - private final int BUILDER_VAR = 3; - private int nextLocalVar = 4; // index to next local variable + private final int BUILDER_VAR = 2; // name of class to generate private final ClassDesc classDesc; @@ -560,8 +562,8 @@ static class SystemModulesClassGenerator { // A builder to create one single Set instance for a given set of // names or modifiers to reduce the footprint // e.g. target modules of qualified exports - private final DedupSetBuilder dedupSetBuilder - = new DedupSetBuilder(this::getNextLocalVar); + private final DedupSetBuilder dedupSetBuilder; + private final ArrayList clinitSnippets = new ArrayList<>(); public SystemModulesClassGenerator(String className, List moduleInfos, @@ -569,13 +571,10 @@ public SystemModulesClassGenerator(String className, this.classDesc = ClassDesc.ofInternalName(className); this.moduleInfos = moduleInfos; this.moduleDescriptorsPerMethod = moduleDescriptorsPerMethod; + this.dedupSetBuilder = new DedupSetBuilder(this.classDesc); moduleInfos.forEach(mi -> dedups(mi.descriptor())); } - private int getNextLocalVar() { - return nextLocalVar++; - } - /* * Adds the given ModuleDescriptor to the system module list. * It performs link-time validation and prepares mapping from various @@ -636,6 +635,9 @@ public byte[] genClassBytes(Configuration cf) { // generate moduleReads genModuleReads(clb, cf); + + // generate static initializer + genClassInitializer(clb); }); } @@ -654,6 +656,19 @@ private void genConstructor(ClassBuilder clb) { .return_()); } + private void genClassInitializer(ClassBuilder clb) { + if (!clinitSnippets.isEmpty()) { + clb.withMethodBody( + CLASS_INIT_NAME, + MTD_void, + ACC_STATIC, + cob -> { + clinitSnippets.forEach(s -> s.emit(cob)); + cob.return_(); + }); + } + } + /** * Generate bytecode for hasSplitPackages method */ @@ -694,146 +709,25 @@ private void genIncubatorModules(ClassBuilder clb) { * Generate bytecode for moduleDescriptors method */ private void genModuleDescriptorsMethod(ClassBuilder clb) { - if (moduleInfos.size() <= moduleDescriptorsPerMethod) { - clb.withMethodBody( - "moduleDescriptors", - MTD_ModuleDescriptorArray, - ACC_PUBLIC, - cob -> { - cob.loadConstant(moduleInfos.size()) - .anewarray(CD_MODULE_DESCRIPTOR) - .astore(MD_VAR); - - for (int index = 0; index < moduleInfos.size(); index++) { - ModuleInfo minfo = moduleInfos.get(index); - new ModuleDescriptorBuilder(cob, - minfo.descriptor(), - minfo.packages(), - index).build(); - } - cob.aload(MD_VAR) - .areturn(); - }); - return; - } - + var dedupSets = dedupSetBuilder.build(clb); + dedupSets.cacheSetupSnippet().ifPresent(clinitSnippets::add); - // Split the module descriptors be created by multiple helper methods. - // Each helper method "subi" creates the maximum N number of module descriptors - // mi, m{i+1} ... - // to avoid exceeding the 64kb limit of method length. Then it will call - // "sub{i+1}" to creates the next batch of module descriptors m{i+n}, m{i+n+1}... - // and so on. During the construction of the module descriptors, the string sets and - // modifier sets are deduplicated (see SystemModulesClassGenerator.DedupSetBuilder) - // and cached in the locals. These locals are saved in an array list so - // that the helper method can restore the local variables that may be - // referenced by the bytecode generated for creating module descriptors. - // Pseudo code looks like this: - // - // void subi(ModuleDescriptor[] mdescs, ArrayList localvars) { - // // assign localvars to local variables - // var l3 = localvars.get(0); - // var l4 = localvars.get(1); - // : - // // fill mdescs[i] to mdescs[i+n-1] - // mdescs[i] = ... - // mdescs[i+1] = ... - // : - // // save new local variables added - // localvars.add(lx) - // localvars.add(l{x+1}) - // : - // sub{i+i}(mdescs, localvars); - // } - - List> splitModuleInfos = new ArrayList<>(); - List currentModuleInfos = null; - for (int index = 0; index < moduleInfos.size(); index++) { - if (index % moduleDescriptorsPerMethod == 0) { - currentModuleInfos = new ArrayList<>(); - splitModuleInfos.add(currentModuleInfos); - } - currentModuleInfos.add(moduleInfos.get(index)); - } - - String helperMethodNamePrefix = "sub"; - ClassDesc arrayListClassDesc = ClassDesc.ofInternalName("java/util/ArrayList"); + var converter = new ModuleDescriptorBuilder(clb, dedupSets, classDesc); + var elementSnippets = converter.buildAll(moduleInfos); + var moduleDescriptors = new ArraySnippetBuilder(CD_MODULE_DESCRIPTOR) + .classBuilder(clb) + .ownerClassDesc(classDesc) + .enablePagination("sub", moduleDescriptorsPerMethod) + .build(elementSnippets); clb.withMethodBody( "moduleDescriptors", MTD_ModuleDescriptorArray, ACC_PUBLIC, cob -> { - cob.loadConstant(moduleInfos.size()) - .anewarray(CD_MODULE_DESCRIPTOR) - .dup() - .astore(MD_VAR); - cob.new_(arrayListClassDesc) - .dup() - .loadConstant(moduleInfos.size()) - .invokespecial(arrayListClassDesc, INIT_NAME, MethodTypeDesc.of(CD_void, CD_int)) - .astore(DEDUP_LIST_VAR); - cob.aload(0) - .aload(MD_VAR) - .aload(DEDUP_LIST_VAR) - .invokevirtual( - this.classDesc, - helperMethodNamePrefix + "0", - MethodTypeDesc.of(CD_void, CD_MODULE_DESCRIPTOR.arrayType(), arrayListClassDesc) - ) - .areturn(); + moduleDescriptors.emit(cob); + cob.areturn(); }); - - int dedupVarStart = nextLocalVar; - for (int n = 0, count = 0; n < splitModuleInfos.size(); count += splitModuleInfos.get(n).size(), n++) { - int index = n; // the index of which ModuleInfo being processed in the current batch - int start = count; // the start index to the return ModuleDescriptor array for the current batch - int curDedupVar = nextLocalVar; - clb.withMethodBody( - helperMethodNamePrefix + index, - MethodTypeDesc.of(CD_void, CD_MODULE_DESCRIPTOR.arrayType(), arrayListClassDesc), - ACC_PUBLIC, - cob -> { - if (curDedupVar > dedupVarStart) { - for (int i = dedupVarStart; i < curDedupVar; i++) { - cob.aload(DEDUP_LIST_VAR) - .loadConstant(i - dedupVarStart) - .invokevirtual(arrayListClassDesc, "get", MethodTypeDesc.of(CD_Object, CD_int)) - .astore(i); - } - } - - List currentBatch = splitModuleInfos.get(index); - for (int j = 0; j < currentBatch.size(); j++) { - ModuleInfo minfo = currentBatch.get(j); - new ModuleDescriptorBuilder(cob, - minfo.descriptor(), - minfo.packages(), - start + j).build(); - } - - if (index < splitModuleInfos.size() - 1) { - if (nextLocalVar > curDedupVar) { - for (int i = curDedupVar; i < nextLocalVar; i++) { - cob.aload(DEDUP_LIST_VAR) - .aload(i) - .invokevirtual(arrayListClassDesc, "add", MethodTypeDesc.of(CD_boolean, CD_Object)) - .pop(); - } - } - cob.aload(0) - .aload(MD_VAR) - .aload(DEDUP_LIST_VAR) - .invokevirtual( - this.classDesc, - helperMethodNamePrefix + (index+1), - MethodTypeDesc.of(CD_void, CD_MODULE_DESCRIPTOR.arrayType(), arrayListClassDesc) - ); - } - - cob.return_(); - }); - } } /** @@ -977,6 +871,7 @@ private void generate(ClassBuilder clb, // map of Set -> local Map, Integer> locals; + int setBuilt = 0; // generate code to create the sets that are duplicated if (dedup) { @@ -988,7 +883,7 @@ private void generate(ClassBuilder clb, locals = new HashMap<>(); int index = 1; for (Set s : duplicateSets) { - genImmutableSet(cob, s); + genImmutableSet(clb, cob, s, methodName + setBuilt++); cob.astore(index); locals.put(s, index); if (++index >= MAX_LOCAL_VARS) { @@ -1015,7 +910,7 @@ private void generate(ClassBuilder clb, // if de-duplicated then load the local, otherwise generate code Integer varIndex = locals.get(s); if (varIndex == null) { - genImmutableSet(cob, s); + genImmutableSet(clb, cob, s, methodName + setBuilt++); } else { cob.aload(varIndex); } @@ -1040,449 +935,14 @@ private void generate(ClassBuilder clb, /** * Generate code to generate an immutable set. */ - private void genImmutableSet(CodeBuilder cob, Set set) { - int size = set.size(); - - // use Set.of(Object[]) when there are more than 2 elements - // use Set.of(Object) or Set.of(Object, Object) when fewer - if (size > 2) { - cob.loadConstant(size) - .anewarray(CD_String); - int i = 0; - for (String element : sorted(set)) { - cob.dup() - .loadConstant(i) - .loadConstant(element) - .aastore(); - i++; - } - cob.invokestatic(CD_Set, - "of", - MTD_Set_ObjectArray, - true); - } else { - for (String element : sorted(set)) { - cob.loadConstant(element); - } - var mtdArgs = new ClassDesc[size]; - Arrays.fill(mtdArgs, CD_Object); - cob.invokestatic(CD_Set, - "of", - MethodTypeDesc.of(CD_Set, mtdArgs), - true); - } - } - - class ModuleDescriptorBuilder { - static final ClassDesc CD_EXPORTS = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Exports"); - static final ClassDesc CD_OPENS = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Opens"); - static final ClassDesc CD_PROVIDES = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Provides"); - static final ClassDesc CD_REQUIRES = - ClassDesc.ofInternalName("java/lang/module/ModuleDescriptor$Requires"); - - // method signature for static Builder::newExports, newOpens, - // newProvides, newRequires methods - static final MethodTypeDesc MTD_EXPORTS_MODIFIER_SET_STRING_SET = - MethodTypeDesc.of(CD_EXPORTS, CD_Set, CD_String, CD_Set); - static final MethodTypeDesc MTD_EXPORTS_MODIFIER_SET_STRING = - MethodTypeDesc.of(CD_EXPORTS, CD_Set, CD_String); - static final MethodTypeDesc MTD_OPENS_MODIFIER_SET_STRING_SET = - MethodTypeDesc.of(CD_OPENS, CD_Set, CD_String, CD_Set); - static final MethodTypeDesc MTD_OPENS_MODIFIER_SET_STRING = - MethodTypeDesc.of(CD_OPENS, CD_Set, CD_String); - static final MethodTypeDesc MTD_PROVIDES_STRING_LIST = - MethodTypeDesc.of(CD_PROVIDES, CD_String, CD_List); - static final MethodTypeDesc MTD_REQUIRES_SET_STRING = - MethodTypeDesc.of(CD_REQUIRES, CD_Set, CD_String); - static final MethodTypeDesc MTD_REQUIRES_SET_STRING_STRING = - MethodTypeDesc.of(CD_REQUIRES, CD_Set, CD_String, CD_String); - - // method signature for Builder instance methods that - // return this Builder instance - static final MethodTypeDesc MTD_EXPORTS_ARRAY = - MethodTypeDesc.of(CD_MODULE_BUILDER, CD_EXPORTS.arrayType()); - static final MethodTypeDesc MTD_OPENS_ARRAY = - MethodTypeDesc.of(CD_MODULE_BUILDER, CD_OPENS.arrayType()); - static final MethodTypeDesc MTD_PROVIDES_ARRAY = - MethodTypeDesc.of(CD_MODULE_BUILDER, CD_PROVIDES.arrayType()); - static final MethodTypeDesc MTD_REQUIRES_ARRAY = - MethodTypeDesc.of(CD_MODULE_BUILDER, CD_REQUIRES.arrayType()); - static final MethodTypeDesc MTD_SET = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_Set); - static final MethodTypeDesc MTD_STRING = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_String); - static final MethodTypeDesc MTD_BOOLEAN = MethodTypeDesc.of(CD_MODULE_BUILDER, CD_boolean); - static final MethodTypeDesc MTD_void_String = MethodTypeDesc.of(CD_void, CD_String); - static final MethodTypeDesc MTD_ModuleDescriptor_int = MethodTypeDesc.of(CD_MODULE_DESCRIPTOR, CD_int); - static final MethodTypeDesc MTD_List_ObjectArray = MethodTypeDesc.of(CD_List, CD_Object.arrayType()); - - final CodeBuilder cob; - final ModuleDescriptor md; - final Set packages; - final int index; - - ModuleDescriptorBuilder(CodeBuilder cob, ModuleDescriptor md, Set packages, int index) { - if (md.isAutomatic()) { - throw new InternalError("linking automatic module is not supported"); - } - this.cob = cob; - this.md = md; - this.packages = packages; - this.index = index; - } - - void build() { - // new jdk.internal.module.Builder - newBuilder(); - - // requires - requires(md.requires()); - - // exports - exports(md.exports()); - - // opens - opens(md.opens()); - - // uses - uses(md.uses()); - - // provides - provides(md.provides()); - - // all packages - packages(packages); - - // version - md.version().ifPresent(this::version); - - // main class - md.mainClass().ifPresent(this::mainClass); - - putModuleDescriptor(); - } - - void newBuilder() { - cob.new_(CD_MODULE_BUILDER) - .dup() - .loadConstant(md.name()) - .invokespecial(CD_MODULE_BUILDER, - INIT_NAME, - MTD_void_String) - .astore(BUILDER_VAR); - - if (md.isOpen()) { - setModuleBit("open", true); - } - if (md.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC)) { - setModuleBit("synthetic", true); - } - if (md.modifiers().contains(ModuleDescriptor.Modifier.MANDATED)) { - setModuleBit("mandated", true); - } - } - - /* - * Invoke Builder.(boolean value) - */ - void setModuleBit(String methodName, boolean value) { - cob.aload(BUILDER_VAR) - .loadConstant(value ? 1 : 0) - .invokevirtual(CD_MODULE_BUILDER, - methodName, - MTD_BOOLEAN) - .pop(); - } - - /* - * Put ModuleDescriptor into the modules array - */ - void putModuleDescriptor() { - cob.aload(MD_VAR) - .loadConstant(index) - .aload(BUILDER_VAR) - .loadConstant(md.hashCode()) - .invokevirtual(CD_MODULE_BUILDER, - "build", - MTD_ModuleDescriptor_int) - .aastore(); - } - - /* - * Call Builder::newRequires to create Requires instances and - * then pass it to the builder by calling: - * Builder.requires(Requires[]) - * - */ - void requires(Set requires) { - cob.aload(BUILDER_VAR) - .loadConstant(requires.size()) - .anewarray(CD_REQUIRES); - int arrayIndex = 0; - for (Requires require : sorted(requires)) { - String compiledVersion = null; - if (require.compiledVersion().isPresent()) { - compiledVersion = require.compiledVersion().get().toString(); - } - - cob.dup() // arrayref - .loadConstant(arrayIndex++); - newRequires(require.modifiers(), require.name(), compiledVersion); - cob.aastore(); - } - cob.invokevirtual(CD_MODULE_BUILDER, - "requires", - MTD_REQUIRES_ARRAY) - .pop(); - } - - /* - * Invoke Builder.newRequires(Set mods, String mn, String compiledVersion) - * - * Set mods = ... - * Builder.newRequires(mods, mn, compiledVersion); - */ - void newRequires(Set mods, String name, String compiledVersion) { - int varIndex = dedupSetBuilder.indexOfRequiresModifiers(cob, mods); - cob.aload(varIndex) - .loadConstant(name); - if (compiledVersion != null) { - cob.loadConstant(compiledVersion) - .invokestatic(CD_MODULE_BUILDER, - "newRequires", - MTD_REQUIRES_SET_STRING_STRING); - } else { - cob.invokestatic(CD_MODULE_BUILDER, - "newRequires", - MTD_REQUIRES_SET_STRING); - } - } - - /* - * Call Builder::newExports to create Exports instances and - * then pass it to the builder by calling: - * Builder.exports(Exports[]) - * - */ - void exports(Set exports) { - cob.aload(BUILDER_VAR) - .loadConstant(exports.size()) - .anewarray(CD_EXPORTS); - int arrayIndex = 0; - for (Exports export : sorted(exports)) { - cob.dup() // arrayref - .loadConstant(arrayIndex++); - newExports(export.modifiers(), export.source(), export.targets()); - cob.aastore(); - } - cob.invokevirtual(CD_MODULE_BUILDER, - "exports", - MTD_EXPORTS_ARRAY) - .pop(); - } - - /* - * Invoke - * Builder.newExports(Set ms, String pn, - * Set targets) - * or - * Builder.newExports(Set ms, String pn) - * - * Set targets = new HashSet<>(); - * targets.add(t); - * : - * : - * - * Set mods = ... - * Builder.newExports(mods, pn, targets); - */ - void newExports(Set ms, String pn, Set targets) { - int modifiersSetIndex = dedupSetBuilder.indexOfExportsModifiers(cob, ms); - if (!targets.isEmpty()) { - int stringSetIndex = dedupSetBuilder.indexOfStringSet(cob, targets); - cob.aload(modifiersSetIndex) - .loadConstant(pn) - .aload(stringSetIndex) - .invokestatic(CD_MODULE_BUILDER, - "newExports", - MTD_EXPORTS_MODIFIER_SET_STRING_SET); - } else { - cob.aload(modifiersSetIndex) - .loadConstant(pn) - .invokestatic(CD_MODULE_BUILDER, - "newExports", - MTD_EXPORTS_MODIFIER_SET_STRING); - } - } - - - /** - * Call Builder::newOpens to create Opens instances and - * then pass it to the builder by calling: - * Builder.opens(Opens[]) - */ - void opens(Set opens) { - cob.aload(BUILDER_VAR) - .loadConstant(opens.size()) - .anewarray(CD_OPENS); - int arrayIndex = 0; - for (Opens open : sorted(opens)) { - cob.dup() // arrayref - .loadConstant(arrayIndex++); - newOpens(open.modifiers(), open.source(), open.targets()); - cob.aastore(); - } - cob.invokevirtual(CD_MODULE_BUILDER, - "opens", - MTD_OPENS_ARRAY) - .pop(); - } - - /* - * Invoke - * Builder.newOpens(Set ms, String pn, - * Set targets) - * or - * Builder.newOpens(Set ms, String pn) - * - * Set targets = new HashSet<>(); - * targets.add(t); - * : - * : - * - * Set mods = ... - * Builder.newOpens(mods, pn, targets); - */ - void newOpens(Set ms, String pn, Set targets) { - int modifiersSetIndex = dedupSetBuilder.indexOfOpensModifiers(cob, ms); - if (!targets.isEmpty()) { - int stringSetIndex = dedupSetBuilder.indexOfStringSet(cob, targets); - cob.aload(modifiersSetIndex) - .loadConstant(pn) - .aload(stringSetIndex) - .invokestatic(CD_MODULE_BUILDER, - "newOpens", - MTD_OPENS_MODIFIER_SET_STRING_SET); - } else { - cob.aload(modifiersSetIndex) - .loadConstant(pn) - .invokestatic(CD_MODULE_BUILDER, - "newOpens", - MTD_OPENS_MODIFIER_SET_STRING); - } - } - - /* - * Invoke Builder.uses(Set uses) - */ - void uses(Set uses) { - int varIndex = dedupSetBuilder.indexOfStringSet(cob, uses); - cob.aload(BUILDER_VAR) - .aload(varIndex) - .invokevirtual(CD_MODULE_BUILDER, - "uses", - MTD_SET) - .pop(); - } - - /* - * Call Builder::newProvides to create Provides instances and - * then pass it to the builder by calling: - * Builder.provides(Provides[] provides) - * - */ - void provides(Collection provides) { - cob.aload(BUILDER_VAR) - .loadConstant(provides.size()) - .anewarray(CD_PROVIDES); - int arrayIndex = 0; - for (Provides provide : sorted(provides)) { - cob.dup() // arrayref - .loadConstant(arrayIndex++); - newProvides(provide.service(), provide.providers()); - cob.aastore(); - } - cob.invokevirtual(CD_MODULE_BUILDER, - "provides", - MTD_PROVIDES_ARRAY) - .pop(); - } - - /* - * Invoke Builder.newProvides(String service, Set providers) - * - * Set providers = new HashSet<>(); - * providers.add(impl); - * : - * : - * Builder.newProvides(service, providers); - */ - void newProvides(String service, List providers) { - cob.loadConstant(service) - .loadConstant(providers.size()) - .anewarray(CD_String); - int arrayIndex = 0; - for (String provider : providers) { - cob.dup() // arrayref - .loadConstant(arrayIndex++) - .loadConstant(provider) - .aastore(); - } - cob.invokestatic(CD_List, - "of", - MTD_List_ObjectArray, - true) - .invokestatic(CD_MODULE_BUILDER, - "newProvides", - MTD_PROVIDES_STRING_LIST); - } - - /* - * Invoke Builder.packages(String pn) - */ - void packages(Set packages) { - int varIndex = dedupSetBuilder.newStringSet(cob, packages); - cob.aload(BUILDER_VAR) - .aload(varIndex) - .invokevirtual(CD_MODULE_BUILDER, - "packages", - MTD_SET) - .pop(); - } - - /* - * Invoke Builder.mainClass(String cn) - */ - void mainClass(String cn) { - cob.aload(BUILDER_VAR) - .loadConstant(cn) - .invokevirtual(CD_MODULE_BUILDER, - "mainClass", - MTD_STRING) - .pop(); - } - - /* - * Invoke Builder.version(Version v); - */ - void version(Version v) { - cob.aload(BUILDER_VAR) - .loadConstant(v.toString()) - .invokevirtual(CD_MODULE_BUILDER, - "version", - MTD_STRING) - .pop(); - } - - void invokeBuilderMethod(String methodName, String value) { - cob.aload(BUILDER_VAR) - .loadConstant(value) - .invokevirtual(CD_MODULE_BUILDER, - methodName, - MTD_STRING) - .pop(); - } + private void genImmutableSet(ClassBuilder clb, CodeBuilder cob, Set set, String methodNamePrefix) { + var snippets = Snippet.buildAll(sorted(set), Snippet::loadConstant); + new SetSnippetBuilder(CD_String) + .classBuilder(clb) + .ownerClassDesc(classDesc) + .enablePagination(methodNamePrefix, STRING_PAGE_SIZE) + .build(snippets) + .emit(cob); } class ModuleHashesBuilder { @@ -1577,240 +1037,234 @@ void hashForModule(String name, byte[] hash) { } } + /* + * Snippets to load the deduplicated set onto the operand stack. + * Set referenced more than once will be read from the cache, cacheSetupSnippet contains + * the bytecode to populate that cache. + */ + static record DedupSnippets(Map, Snippet> stringSets, + Map, Snippet> requiresModifiersSets, + Map, Snippet> opensModifiersSets, + Map, Snippet> exportsModifiersSets, + Optional cacheSetupSnippet) {}; + /* * Wraps set creation, ensuring identical sets are properly deduplicated. */ static class DedupSetBuilder { - // map Set to a specialized builder to allow them to be - // deduplicated as they are requested - final Map, SetBuilder> stringSets = new HashMap<>(); - - // map Set to a specialized builder to allow them to be - // deduplicated as they are requested - final Map, EnumSetBuilder> + final Map, RefCounter> stringSets = new HashMap<>(); + final Map, RefCounter> requiresModifiersSets = new HashMap<>(); - - // map Set to a specialized builder to allow them to be - // deduplicated as they are requested - final Map, EnumSetBuilder> + final Map, RefCounter> exportsModifiersSets = new HashMap<>(); - - // map Set to a specialized builder to allow them to be - // deduplicated as they are requested - final Map, EnumSetBuilder> + final Map, RefCounter> opensModifiersSets = new HashMap<>(); - private final int stringSetVar; - private final int enumSetVar; - private final IntSupplier localVarSupplier; + final ClassDesc owner; + final CacheBuilder cacheBuilder = new CacheBuilder(); + int setBuilt = 0; - DedupSetBuilder(IntSupplier localVarSupplier) { - this.stringSetVar = localVarSupplier.getAsInt(); - this.enumSetVar = localVarSupplier.getAsInt(); - this.localVarSupplier = localVarSupplier; + DedupSetBuilder(ClassDesc owner) { + this.owner = owner; } /* * Add the given set of strings to this builder. */ void stringSet(Set strings) { - stringSets.computeIfAbsent(strings, - s -> new SetBuilder<>(s, stringSetVar, localVarSupplier) - ).increment(); + stringSets.computeIfAbsent(strings, RefCounter::new).increment(); } /* * Add the given set of Exports.Modifiers */ void exportsModifiers(Set mods) { - exportsModifiersSets.computeIfAbsent(mods, s -> - new EnumSetBuilder<>(s, CD_EXPORTS_MODIFIER, - enumSetVar, localVarSupplier) - ).increment(); + exportsModifiersSets.computeIfAbsent(mods, RefCounter::new).increment(); } /* * Add the given set of Opens.Modifiers */ void opensModifiers(Set mods) { - opensModifiersSets.computeIfAbsent(mods, s -> - new EnumSetBuilder<>(s, CD_OPENS_MODIFIER, - enumSetVar, localVarSupplier) - ).increment(); + opensModifiersSets.computeIfAbsent(mods, RefCounter::new).increment(); } /* * Add the given set of Requires.Modifiers */ void requiresModifiers(Set mods) { - requiresModifiersSets.computeIfAbsent(mods, s -> - new EnumSetBuilder<>(s, CD_REQUIRES_MODIFIER, - enumSetVar, localVarSupplier) - ).increment(); + requiresModifiersSets.computeIfAbsent(mods, RefCounter::new).increment(); } /* - * Retrieve the index to the given set of Strings. Emit code to - * generate it when SetBuilder::build is called. + * Generate bytecode to load a set onto the operand stack. + * Use cache if the set is referenced more than once. */ - int indexOfStringSet(CodeBuilder cob, Set names) { - return stringSets.get(names).build(cob); + private Snippet buildStringSet(ClassBuilder clb, RefCounter setRef) { + return cacheBuilder.transform(setRef, + new SetSnippetBuilder(CD_String) + .classBuilder(clb) + .ownerClassDesc(owner) + .enablePagination("dedupSet" + setBuilt++, STRING_PAGE_SIZE) + .build(Snippet.buildAll(setRef.sortedList(), Snippet::loadConstant))); } /* - * Retrieve the index to the given set of Exports.Modifier. - * Emit code to generate it when EnumSetBuilder::build is called. + * Generate the mapping from a set to the bytecode loading the set onto the operand stack. + * Ordering the sets to ensure same generated bytecode. */ - int indexOfExportsModifiers(CodeBuilder cob, Set mods) { - return exportsModifiersSets.get(mods).build(cob); + private Map, Snippet> buildStringSets(ClassBuilder clb, Map, RefCounter> map) { + Map, Snippet> snippets = new HashMap<>(map.size()); + map.entrySet().stream() + .sorted(Map.Entry.comparingByValue()) + .forEach(e -> snippets.put(e.getKey(), buildStringSet(clb, e.getValue()))); + return snippets; } - /** - * Retrieve the index to the given set of Opens.Modifier. - * Emit code to generate it when EnumSetBuilder::build is called. + /* + * Enum set support */ - int indexOfOpensModifiers(CodeBuilder cob, Set mods) { - return opensModifiersSets.get(mods).build(cob); + private > Snippet buildEnumSet(ClassBuilder clb, RefCounter setRef) { + return cacheBuilder.transform(setRef, + new SetSnippetBuilder(CD_Object) + .classBuilder(clb) + .ownerClassDesc(owner) + .enablePagination("dedupSet" + setBuilt++, ENUM_PAGE_SIZE) + .build(Snippet.buildAll(setRef.sortedList(), Snippet::loadEnum))); } + private > Map, Snippet> buildEnumSets(ClassBuilder clb, Map, RefCounter> map) { + Map, Snippet> snippets = new HashMap<>(map.size()); + map.entrySet().stream() + .sorted(Map.Entry.comparingByValue()) + .forEach(e -> snippets.put(e.getKey(), buildEnumSet(clb, e.getValue()))); + return snippets; + } /* - * Retrieve the index to the given set of Requires.Modifier. - * Emit code to generate it when EnumSetBuilder::build is called. + * Build snippets for all sets and optionally the cache. */ - int indexOfRequiresModifiers(CodeBuilder cob, Set mods) { - return requiresModifiersSets.get(mods).build(cob); + DedupSnippets build(ClassBuilder clb) { + return new DedupSnippets( + buildStringSets(clb, stringSets), + buildEnumSets(clb, requiresModifiersSets), + buildEnumSets(clb, opensModifiersSets), + buildEnumSets(clb, exportsModifiersSets), + cacheBuilder.build(clb) + ); } /* - * Build a new string set without any attempt to deduplicate it. + * RefCounter count references to the set, and keeps sorted elements to ensure + * generate same bytecode for a given set. + * RefCounter itself needs ordering to ensure generate same bytecode for the cache. */ - int newStringSet(CodeBuilder cob, Set names) { - int index = new SetBuilder<>(names, stringSetVar, localVarSupplier).build(cob); - assert index == stringSetVar; - return index; - } - } + class RefCounter> implements Comparable> { + // sorted elements of the set to ensure same generated code + private final List elements; + private int refCount; - /* - * SetBuilder generates bytecode to create one single instance of Set - * for a given set of elements and assign to a local variable slot. - * When there is only one single reference to a Set, - * it will reuse defaultVarIndex. For a Set with multiple references, - * it will use a new local variable retrieved from the nextLocalVar - */ - static class SetBuilder> { - private static final MethodTypeDesc MTD_Set_ObjectArray = MethodTypeDesc.of( - CD_Set, CD_Object.arrayType()); - - private final Set elements; - private final int defaultVarIndex; - private final IntSupplier nextLocalVar; - private int refCount; - private int localVarIndex; - - SetBuilder(Set elements, - int defaultVarIndex, - IntSupplier nextLocalVar) { - this.elements = elements; - this.defaultVarIndex = defaultVarIndex; - this.nextLocalVar = nextLocalVar; - } + RefCounter(Set elements) { + this.elements = sorted(elements); + } - /* - * Increments the number of references to this particular set. - */ - final void increment() { - refCount++; + int increment() { + return ++refCount; + } + + int refCount() { + return refCount; + } + + List sortedList() { + return elements; + } + + @Override + public int compareTo(RefCounter o) { + if (o == this) { + return 0; + } + if (elements.size() == o.elements.size()) { + var a1 = elements; + var a2 = o.elements; + for (int i = 0; i < elements.size(); i++) { + var r = a1.get(i).compareTo(a2.get(i)); + if (r != 0) { + return r; + } + } + return 0; + } else { + return elements.size() - o.elements.size(); + } + } } /** - * Generate the appropriate instructions to load an object reference - * to the element onto the stack. + * Build an array to host sets referenced more than once so a given set will only be constructed once. + * Transform the bytecode for loading the set onto the operand stack as needed. */ - void visitElement(T element, CodeBuilder cob) { - cob.loadConstant((ConstantDesc)element); - } + class CacheBuilder { + private static final String VALUES_ARRAY = "dedupSetValues"; + final ArrayList cachedValues = new ArrayList<>(); + + // Load the set from the cache to the operand stack + // dedupSetValues[index] + private Snippet loadFromCache(int index) { + assert index >= 0; + return cob -> + cob.getstatic(owner, VALUES_ARRAY, CD_Set.arrayType()) + .loadConstant(index) + .aaload(); + } - /* - * Build bytecode for the Set represented by this builder, - * or get the local variable index of a previously generated set - * (in the local scope). - * - * @return local variable index of the generated set. - */ - final int build(CodeBuilder cob) { - int index = localVarIndex; - if (localVarIndex == 0) { - // if non-empty and more than one set reference this builder, - // emit to a unique local - index = refCount <= 1 ? defaultVarIndex - : nextLocalVar.getAsInt(); - if (index < MAX_LOCAL_VARS) { - localVarIndex = index; + /** + * Transform the bytecode for loading the set onto the operand stack. + * @param loadSnippet The origin snippet to load the set onto the operand stack. + */ + Snippet transform(RefCounter setRef, Snippet loadSnippet) { + if (setRef.refCount() > 1) { + cachedValues.add(loadSnippet); + return loadFromCache(cachedValues.size() - 1); } else { - // overflow: disable optimization by using localVarIndex = 0 - index = defaultVarIndex; + return loadSnippet; } - - generateSetOf(cob, index); } - return index; - } - private void generateSetOf(CodeBuilder cob, int index) { - if (elements.size() <= 10) { - // call Set.of(e1, e2, ...) - for (T t : sorted(elements)) { - visitElement(t, cob); + /* + * Returns a snippet that populates the cached values in . + * + * The generated cache is essentially as the following: + * + * static final Set[] dedupSetValues; + * + * static { + * dedupSetValues = new Set[countOfStoredValues]; + * dedupSetValues[0] = Set.of(elements); // for inline set + * dedupSetValues[1] = dedupSet_0(); // for paginated set + * ... + * dedupSetValues[countOfStoredValues - 1] = ... + * } + */ + Optional build(ClassBuilder clb) { + if (cachedValues.isEmpty()) { + return Optional.empty(); } - var mtdArgs = new ClassDesc[elements.size()]; - Arrays.fill(mtdArgs, CD_Object); - cob.invokestatic(CD_Set, - "of", - MethodTypeDesc.of(CD_Set, mtdArgs), - true); - } else { - // call Set.of(E... elements) - cob.loadConstant(elements.size()) - .anewarray(CD_String); - int arrayIndex = 0; - for (T t : sorted(elements)) { - cob.dup() // arrayref - .loadConstant(arrayIndex); - visitElement(t, cob); // value - cob.aastore(); - arrayIndex++; - } - cob.invokestatic(CD_Set, - "of", - MTD_Set_ObjectArray, - true); - } - cob.astore(index); - } - } - /* - * Generates bytecode to create one single instance of EnumSet - * for a given set of modifiers and assign to a local variable slot. - */ - static class EnumSetBuilder> extends SetBuilder { - private final ClassDesc classDesc; - - EnumSetBuilder(Set modifiers, ClassDesc classDesc, - int defaultVarIndex, - IntSupplier nextLocalVar) { - super(modifiers, defaultVarIndex, nextLocalVar); - this.classDesc = classDesc; - } + var cacheValuesArray = new ArraySnippetBuilder(CD_Set) + .classBuilder(clb) + .ownerClassDesc(owner) + .enablePagination(VALUES_ARRAY) + .build(cachedValues.toArray(Snippet[]::new)); - /** - * Loads an Enum field. - */ - @Override - void visitElement(T t, CodeBuilder cob) { - cob.getstatic(classDesc, t.toString(), classDesc); + clb.withField(VALUES_ARRAY, CD_Set.arrayType(), ACC_STATIC | ACC_FINAL); + + return Optional.of(cob -> { + cacheValuesArray.emit(cob); + cob.putstatic(owner, VALUES_ARRAY, CD_Set.arrayType()); + }); + } } } } diff --git a/test/jdk/tools/jlink/JLink20000Packages.java b/test/jdk/tools/jlink/JLink20000Packages.java new file mode 100644 index 00000000000..865cf7ca98c --- /dev/null +++ b/test/jdk/tools/jlink/JLink20000Packages.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.StringJoiner; +import java.util.spi.ToolProvider; + +import tests.JImageGenerator; + +/* + * @test + * @summary Make sure that ~20000 packages in a uber jar can be linked using jlink. Now that + * pagination is in place, the limitation is on the constant pool size, not number + * of packages. + * @bug 8321413 + * @library ../lib + * @enablePreview + * @modules java.base/jdk.internal.jimage + * jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jlink.plugin + * jdk.jlink/jdk.tools.jmod + * jdk.jlink/jdk.tools.jimage + * jdk.compiler + * @build tests.* + * @run main/othervm -Xmx1g -Xlog:init=debug -XX:+UnlockDiagnosticVMOptions -XX:+BytecodeVerificationLocal JLink20000Packages + */ +public class JLink20000Packages { + private static final ToolProvider JAVAC_TOOL = ToolProvider.findFirst("javac") + .orElseThrow(() -> new RuntimeException("javac tool not found")); + + static void report(String command, String[] args) { + System.out.println(command + " " + String.join(" ", Arrays.asList(args))); + } + + static void javac(String[] args) { + report("javac", args); + JAVAC_TOOL.run(System.out, System.err, args); + } + + public static void main(String[] args) throws Exception { + Path src = Paths.get("bug8321413"); + Path imageDir = src.resolve("out-jlink"); + Path mainModulePath = src.resolve("bug8321413x"); + + StringJoiner mainModuleInfoContent = new StringJoiner(";\n exports ", "module bug8321413x {\n exports ", ";\n}"); + + for (int i = 0; i < 20000; i++) { + String packageName = "p" + i; + String className = "C" + i; + + Path packagePath = Files.createDirectories(mainModulePath.resolve(packageName)); + + StringBuilder classContent = new StringBuilder("package "); + classContent.append(packageName).append(";\n"); + classContent.append("class ").append(className).append(" {}\n"); + Files.writeString(packagePath.resolve(className + ".java"), classContent.toString()); + + mainModuleInfoContent.add(packageName); + } + + // create module reading the generated modules + Path mainModuleInfo = mainModulePath.resolve("module-info.java"); + Files.writeString(mainModuleInfo, mainModuleInfoContent.toString()); + + Path mainClassDir = mainModulePath.resolve("testpackage"); + Files.createDirectories(mainClassDir); + + Files.writeString(mainClassDir.resolve("JLink20000PackagesTest.java"), """ + package testpackage; + + public class JLink20000PackagesTest { + public static void main(String[] args) throws Exception { + System.out.println("JLink20000PackagesTest started."); + } + } + """); + + String out = src.resolve("out").toString(); + javac(new String[]{ + "-d", out, + "--module-source-path", src.toString(), + "--module", "bug8321413x" + }); + + JImageGenerator.getJLinkTask() + .modulePath(out) + .output(imageDir) + .addMods("bug8321413x") + .call() + .assertSuccess(); + + Path binDir = imageDir.resolve("bin").toAbsolutePath(); + Path bin = binDir.resolve("java"); + + ProcessBuilder processBuilder = new ProcessBuilder(bin.toString(), + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+BytecodeVerificationLocal", + "-m", "bug8321413x/testpackage.JLink20000PackagesTest"); + processBuilder.inheritIO(); + processBuilder.directory(binDir.toFile()); + Process process = processBuilder.start(); + int exitCode = process.waitFor(); + if (exitCode != 0) + throw new AssertionError("JLink20000PackagesTest failed to launch"); + } +} diff --git a/test/jdk/tools/jlink/SnippetsTest.java b/test/jdk/tools/jlink/SnippetsTest.java new file mode 100644 index 00000000000..ec0c94e3d26 --- /dev/null +++ b/test/jdk/tools/jlink/SnippetsTest.java @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.lang.classfile.ClassBuilder; +import java.lang.classfile.ClassFile; +import static java.lang.classfile.ClassFile.ACC_PUBLIC; +import java.lang.constant.ClassDesc; +import static java.lang.constant.ConstantDescs.CD_Integer; +import static java.lang.constant.ConstantDescs.CD_Object; +import static java.lang.constant.ConstantDescs.CD_String; +import static java.lang.constant.ConstantDescs.INIT_NAME; +import static java.lang.constant.ConstantDescs.MTD_void; +import java.lang.constant.MethodTypeDesc; +import static java.lang.invoke.MethodHandles.lookup; +import java.lang.invoke.MethodType; +import java.lang.module.ModuleDescriptor; +import java.lang.reflect.AccessFlag; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import static org.junit.jupiter.api.Assertions.*; + +import jdk.tools.jlink.internal.Snippets.*; + +/* + * @test + * @summary Test snippets generation for array and set. + * @bug 8321413 + * @enablePreview + * @modules jdk.jlink/jdk.tools.jlink.internal + * @run junit SnippetsTest + */ +public class SnippetsTest { + private static final boolean WRITE_CLASS_FILE = Boolean.parseBoolean(System.getProperty("DumpArraySnippetsTestClasses", "false")); + + @ParameterizedTest + @ValueSource(ints = { 10, 75, 90, 120, 200, 399, 400, 401}) + void testLoad400StringsArray(int pageSize) { + testPaginatedArray(400, pageSize); + } + + @Test + void testStringArrayLimitsWithPagination() { + // Each string takes 2 constant pool slot, one for String, another for Utf8 + testPaginatedArray(31_000, 8000); + try { + testPaginatedArray(32_000, 8000); + } catch (IllegalArgumentException iae) { + // expected constant pool explode + } + } + + @Test + void testStringArrayLimitsWithoutPagination() { + // each string array assignment takes ~8 bytes + testSimpleArray(8200); + try { + testSimpleArray(8300); + fail(); + } catch (IllegalArgumentException iae) { + // expected code size explode + } + } + + @Test + void testLoadableEnum() { + Enum[] enums = { + AccessFlag.FINAL, + ModuleDescriptor.Requires.Modifier.MANDATED, + ModuleDescriptor.Opens.Modifier.SYNTHETIC, + ModuleDescriptor.Requires.Modifier.TRANSITIVE + }; + + Snippet[] elementSnippets = Snippet.buildAll(Arrays.asList(enums), Snippet::loadEnum); + + var loadable = new ArraySnippetBuilder(Enum.class.describeConstable().get()) + .build(elementSnippets); + + Supplier[]> supplier = generateSupplier("LoadableEnumTest", clb -> loadable); + assertArrayEquals(enums, supplier.get()); + } + + @Test + void testArraySnippetBuilder() { + Integer[] expected = IntStream.range(0, 200) + .boxed() + .toArray(Integer[]::new); + var className = "LoadableArrayOf200Paged"; + var elementSnippets = Snippet.buildAll(Arrays.asList(expected), Snippet::loadInteger); + var instance = new ArraySnippetBuilder(CD_Integer) + .ownerClassDesc(ClassDesc.of(className)) + .enablePagination("page", 100); + + try { + instance.build(elementSnippets); + fail("Should throw NPE without ClassBuilder"); + } catch (NullPointerException npe) { + // expected + } + + Supplier supplier = generateSupplier(className, clb -> instance.classBuilder(clb).build(elementSnippets)); + verifyPaginationMethods(supplier.getClass(), Integer.class, "page", 2); + assertArrayEquals(expected, supplier.get()); + + var loadable = instance.disablePagination() + .ownerClassDesc(ClassDesc.of("LoadableArrayOf200NotPaged")) + .build(elementSnippets); + + // SimpleArray generate bytecode inline, so can be generated in any class + supplier = generateSupplier("TestLoadableArrayFactory", clb -> loadable); + verifyPaginationMethods(supplier.getClass(), Integer.class, "page", 0); + assertArrayEquals(expected, supplier.get()); + } + + @Test + void testSetSnippetBuilder() { + String[] data = IntStream.range(0, 100) + .mapToObj(i -> "SetData" + i) + .toArray(String[]::new); + + var tiny = Set.of(data[0], data[1], data[2]); + var all = Set.of(data); + var setBuilder = new SetSnippetBuilder(CD_String); + + Supplier> supplier = generateSupplier("TinySetTest", clb -> + setBuilder.build(Snippet.buildAll(tiny, Snippet::loadConstant))); + // Set does not guarantee ordering, so not assertIterableEquals + assertEquals(tiny, supplier.get()); + + var allSnippets = Snippet.buildAll(all, Snippet::loadConstant); + + supplier = generateSupplier("AllSetTestNoPage", clb -> + setBuilder.build(allSnippets)); + assertEquals(all, supplier.get()); + + var className = "AllSetTestPageNotActivated"; + var methodNamePrefix = "page"; + var loadable = setBuilder.disablePagination() + .ownerClassDesc(ClassDesc.of(className)) + .build(allSnippets); + supplier = generateSupplier(className, clb -> loadable); + assertEquals(all, supplier.get()); + + className = "AllSetTestPageSize20"; + setBuilder.ownerClassDesc(ClassDesc.of(className)); + supplier = generateSupplier(className, clb -> setBuilder.classBuilder(clb) + .enablePagination(methodNamePrefix, 20) + .build(allSnippets)); + verifyPaginationMethods(supplier.getClass(), String.class, methodNamePrefix, 5); + assertEquals(all, supplier.get()); + } + + void testPaginatedArray(int elementCount, int pageSize) { + String[] expected = IntStream.range(0, elementCount) + .mapToObj(i -> "Package" + i) + .toArray(String[]::new); + var className = String.format("SnippetArrayProviderTest%dPagedBy%d", elementCount, pageSize); + ClassDesc testClassDesc = ClassDesc.of(className); + var builder = new ArraySnippetBuilder(CD_String) + .enablePagination("ArrayPage", pageSize, 1) + .ownerClassDesc(testClassDesc); + var snippets = Snippet.buildAll(Arrays.asList(expected), Snippet::loadConstant); + var pagingContext = new PagingContext(expected.length, pageSize); + + Supplier supplier = generateSupplier(className, clb -> builder.classBuilder(clb).build(snippets)); + verifyPaginationMethods(supplier.getClass(), String.class, "ArrayPage", pagingContext.pageCount()); + assertEquals((elementCount % pageSize) != 0, pagingContext.isLastPagePartial()); + assertArrayEquals(expected, supplier.get()); + } + + void testSimpleArray(int elementCount) { + String[] expected = IntStream.range(0, elementCount) + .mapToObj(i -> "NoPage" + i) + .toArray(String[]::new); + String className = "SnippetArrayProviderTest" + elementCount; + var array = new ArraySnippetBuilder(CD_String) + .disablePagination() + .build(Snippet.buildAll(Arrays.asList(expected), Snippet::loadConstant)); + + Supplier supplier = generateSupplier(className, clb -> array); + verifyPaginationMethods(supplier.getClass(), String.class, "page", 0); + assertArrayEquals(expected, supplier.get()); + } + + Supplier generateSupplier(String className, Function builder) { + var testClassDesc = ClassDesc.of(className); + byte[] classBytes = generateSupplierClass(testClassDesc, builder); + try { + writeClassFile(className, classBytes); + var testClass = lookup().defineClass(classBytes); + lookup().findVirtual(testClass, "get", MethodType.methodType(Object.class)); + return (Supplier) testClass.getDeclaredConstructor().newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + void verifyPaginationMethods(Class testClass, Class elementType, String methodNamePrefix, int pageCount) { + var methodType = MethodType.methodType(elementType.arrayType(), elementType.arrayType()); + if (pageCount <= 0) { + try { + lookup().findStatic(testClass, methodNamePrefix + "_0", methodType); + fail("Unexpected paginate helper function"); + } catch (Exception ex) {} + } + + for (int i = 0; i < pageCount; i++) { + try { + lookup().findStatic(testClass, methodNamePrefix + "_" + i, methodType); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + } + + byte[] generateSupplierClass(ClassDesc testClassDesc, Function builder) { + return ClassFile.of().build(testClassDesc, + clb -> { + clb.withSuperclass(CD_Object); + clb.withInterfaceSymbols(ClassDesc.ofInternalName("java/util/function/Supplier")); + clb.withMethodBody(INIT_NAME, MTD_void, ACC_PUBLIC, cob -> { + cob.aload(0); + cob.invokespecial(CD_Object, INIT_NAME, MTD_void); + cob.return_(); + }); + + var loadable = builder.apply(clb); + + clb.withMethodBody("get", MethodTypeDesc.of(CD_Object), ACC_PUBLIC, cob -> { + loadable.emit(cob); + cob.areturn(); + }); + }); + } + + void writeClassFile(String className, byte[] classBytes) throws IOException { + if (WRITE_CLASS_FILE) { + Files.write(Path.of(className + ".class"), classBytes); + } + } +} \ No newline at end of file From 92536e1f15faa4c6636ac2686ce35d7d75e9f94e Mon Sep 17 00:00:00 2001 From: Harshitha Onkar Date: Thu, 9 Jan 2025 18:22:33 +0000 Subject: [PATCH 20/25] 8344907: NullPointerException in Win32ShellFolder2.getSystemIcon when "icon" is null Reviewed-by: aivanov, kizune --- .../sun/awt/shell/Win32ShellFolder2.java | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java index 0a4fb12cda6..c85c2d4ced9 100644 --- a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java +++ b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1201,8 +1201,12 @@ public Image getIcon(int width, int height) { */ static Image getSystemIcon(SystemIcon iconType) { long hIcon = getSystemIcon(iconType.getIconID()); + if (hIcon == 0) { + return null; + } + Image icon = makeIcon(hIcon); - if (LARGE_ICON_SIZE != icon.getWidth(null)) { + if (icon != null && LARGE_ICON_SIZE != icon.getWidth(null)) { icon = new MultiResolutionIconImage(LARGE_ICON_SIZE, icon); } disposeIcon(hIcon); @@ -1214,15 +1218,16 @@ static Image getSystemIcon(SystemIcon iconType) { */ static Image getShell32Icon(int iconID, int size) { long hIcon = getIconResource("shell32.dll", iconID, size, size); - if (hIcon != 0) { - Image icon = makeIcon(hIcon); - if (size != icon.getWidth(null)) { - icon = new MultiResolutionIconImage(size, icon); - } - disposeIcon(hIcon); - return icon; + if (hIcon == 0) { + return null; } - return null; + + Image icon = makeIcon(hIcon); + if (icon != null && size != icon.getWidth(null)) { + icon = new MultiResolutionIconImage(size, icon); + } + disposeIcon(hIcon); + return icon; } /** From 73941c9642e724f8273775baba79a118772f984d Mon Sep 17 00:00:00 2001 From: Alisen Chung Date: Thu, 9 Jan 2025 20:47:22 +0000 Subject: [PATCH 21/25] 8345144: Robot does not specify all causes of IllegalThreadStateException Reviewed-by: prr --- .../share/classes/java/awt/Robot.java | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/java.desktop/share/classes/java/awt/Robot.java b/src/java.desktop/share/classes/java/awt/Robot.java index 8b7506f5f2d..d0877b3bddd 100644 --- a/src/java.desktop/share/classes/java/awt/Robot.java +++ b/src/java.desktop/share/classes/java/awt/Robot.java @@ -58,6 +58,15 @@ * queue. For example, {@code Robot.mouseMove} will actually move * the mouse cursor instead of just generating mouse move events. *

      + * @apiNote When {@code autoWaitForIdle()} is enabled, mouse and key related methods + * cannot be called on the AWT EDT. This is because when {@code autoWaitForIdle()} + * is enabled, the mouse and key methods implicitly call {@code waitForIdle()} + * which will throw {@code IllegalThreadStateException} when called on the AWT EDT. + * In addition, screen capture operations can be lengthy + * and {@code delay(long ms)} clearly inserts a delay, so these also + * should not be called on the EDT. Taken together, this means that as much as possible, + * methods on this class should not be called on the EDT. + *

      * Note that some platforms require special privileges or extensions * to access low-level input control. If the current platform configuration * does not allow input control, an {@code AWTException} will be thrown @@ -216,6 +225,8 @@ private static void checkIsScreenDevice(GraphicsDevice device) { * * @param x X position * @param y Y position + * @throws IllegalThreadStateException if called on the AWT event dispatching + * thread and {@code isAutoWaitForIdle} would return true */ public synchronized void mouseMove(int x, int y) { peer.mouseMove(x, y); @@ -268,6 +279,7 @@ public synchronized void mouseMove(int x, int y) { * and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for extra mouse button * that does not exist on the mouse and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java + * @throws IllegalThreadStateException if called on the AWT event dispatching thread and {@code isAutoWaitForIdle} would return true * @see #mouseRelease(int) * @see InputEvent#getMaskForButton(int) * @see Toolkit#areExtraMouseButtonsEnabled() @@ -325,6 +337,7 @@ public synchronized void mousePress(int buttons) { * and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() disabled} by Java * @throws IllegalArgumentException if the {@code buttons} mask contains the mask for extra mouse button * that does not exist on the mouse and support for extended mouse buttons is {@link Toolkit#areExtraMouseButtonsEnabled() enabled} by Java + * @throws IllegalThreadStateException if called on the AWT event dispatching thread and {@code isAutoWaitForIdle} would return true * @see #mousePress(int) * @see InputEvent#getMaskForButton(int) * @see Toolkit#areExtraMouseButtonsEnabled() @@ -349,6 +362,8 @@ private static void checkButtonsArgument(int buttons) { * @param wheelAmt number of "notches" to move the mouse wheel * Negative values indicate movement up/away from the user, * positive values indicate movement down/towards the user. + * @throws IllegalThreadStateException if called on the AWT event dispatching + * thread and {@code isAutoWaitForIdle} would return true * * @since 1.4 */ @@ -368,6 +383,8 @@ public synchronized void mouseWheel(int wheelAmt) { * @param keycode Key to press (e.g. {@code KeyEvent.VK_A}) * @throws IllegalArgumentException if {@code keycode} is not * a valid key + * @throws IllegalThreadStateException if called on the AWT event + * dispatching thread and {@code isAutoWaitForIdle} would return true * @see #keyRelease(int) * @see java.awt.event.KeyEvent */ @@ -387,7 +404,9 @@ public synchronized void keyPress(int keycode) { * @param keycode Key to release (e.g. {@code KeyEvent.VK_A}) * @throws IllegalArgumentException if {@code keycode} is not a * valid key - * @see #keyPress(int) + * @throws IllegalThreadStateException if called on the AWT event + * dispatching thread and {@code isAutoWaitForIdle} would return true + * @see #keyPress(int) * @see java.awt.event.KeyEvent */ public synchronized void keyRelease(int keycode) { @@ -487,6 +506,12 @@ public synchronized BufferedImage createScreenCapture(Rectangle screenRect) { * nativeResImage = resolutionVariants.get(0); * } * } + * + * @apiNote It is recommended to avoid calling this method on + * the AWT Event Dispatch Thread since screen capture may be a lengthy + * operation, particularly if acquiring permissions is needed and involves + * user interaction. + * * @param screenRect Rect to capture in screen coordinates * @return The captured image * @throws IllegalArgumentException if {@code screenRect} width and height @@ -641,6 +666,10 @@ public synchronized boolean isAutoWaitForIdle() { /** * Sets whether this Robot automatically invokes {@code waitForIdle} * after generating an event. + *

      + * @apiNote Setting this to true means you cannot call mouse and key-controlling events + * on the AWT Event Dispatching Thread + * * @param isOn Whether {@code waitForIdle} is automatically invoked */ public synchronized void setAutoWaitForIdle(boolean isOn) { @@ -692,6 +721,10 @@ private void autoDelay() { * already set, this method returns immediately with the interrupt status * set. * + * @apiNote It is recommended to avoid calling this method on + * the AWT Event Dispatch Thread since delay may be a lengthy + * operation. + * * @param ms time to sleep in milliseconds * @throws IllegalArgumentException if {@code ms} is not between {@code 0} * and {@code 60,000} milliseconds inclusive From 46cd9be5cb0005824f076f4bdce587fdbaac2918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Thu, 9 Jan 2025 21:37:36 +0000 Subject: [PATCH 22/25] 8347122: Add missing @serial tags to module java.desktop Reviewed-by: prr --- .../share/classes/java/applet/Applet.java | 4 ++-- .../share/classes/java/awt/AWTEvent.java | 4 ++-- .../share/classes/java/awt/AWTKeyStroke.java | 10 ++++----- .../share/classes/java/awt/Component.java | 19 +++++++++------- .../java/awt/ComponentOrientation.java | 4 ++-- .../share/classes/java/awt/Container.java | 3 ++- .../ContainerOrderFocusTraversalPolicy.java | 8 +++---- .../share/classes/java/awt/FlowLayout.java | 4 ++-- .../share/classes/java/awt/Frame.java | 4 ++-- .../share/classes/java/awt/GridBagLayout.java | 4 ++-- .../classes/java/awt/GridBagLayoutInfo.java | 22 +++++++++---------- .../share/classes/java/awt/List.java | 6 ++--- .../share/classes/java/awt/MenuComponent.java | 4 ++-- .../java/awt/ScrollPaneAdjustable.java | 4 ++-- .../share/classes/java/awt/TextComponent.java | 6 ++--- .../share/classes/java/awt/Window.java | 8 +++---- .../classes/java/awt/color/ColorSpace.java | 6 ++--- .../java/awt/color/ICC_ColorSpace.java | 14 ++++++------ .../classes/java/awt/desktop/FilesEvent.java | 4 ++-- .../java/awt/desktop/OpenFilesEvent.java | 4 ++-- .../java/awt/desktop/OpenURIEvent.java | 4 ++-- .../java/awt/desktop/UserSessionEvent.java | 4 ++-- .../java/awt/event/HierarchyEvent.java | 8 +++---- .../java/awt/event/InvocationEvent.java | 15 ++++++++----- .../classes/java/awt/event/KeyEvent.java | 6 ++--- .../classes/java/awt/event/MouseEvent.java | 4 ++-- .../java/awt/event/MouseWheelEvent.java | 10 ++++----- .../classes/java/awt/event/WindowEvent.java | 6 ++--- .../classes/java/awt/font/NumericShaper.java | 8 +++---- .../java/awt/font/TransformAttribute.java | 4 ++-- .../awt/image/renderable/ParameterBlock.java | 12 +++++++--- .../beans/IndexedPropertyChangeEvent.java | 4 ++-- .../beancontext/BeanContextChildSupport.java | 8 ++++++- .../beans/beancontext/BeanContextEvent.java | 4 +++- .../BeanContextMembershipEvent.java | 4 +++- .../BeanContextServiceAvailableEvent.java | 4 +++- .../BeanContextServiceRevokedEvent.java | 6 +++-- .../BeanContextServicesSupport.java | 4 +++- .../beans/beancontext/BeanContextSupport.java | 14 ++++++++---- .../metadata/IIOInvalidTreeException.java | 4 +++- .../attribute/AttributeSetUtilities.java | 6 ++--- .../print/attribute/standard/DialogOwner.java | 4 ++-- .../standard/MediaPrintableArea.java | 6 ++--- .../print/attribute/standard/MediaSize.java | 4 ++-- .../print/event/PrintJobAttributeEvent.java | 4 ++-- .../javax/print/event/PrintJobEvent.java | 4 ++-- .../event/PrintServiceAttributeEvent.java | 4 ++-- 47 files changed, 173 insertions(+), 134 deletions(-) diff --git a/src/java.desktop/share/classes/java/applet/Applet.java b/src/java.desktop/share/classes/java/applet/Applet.java index 2228ea419d4..56b2392f0e2 100644 --- a/src/java.desktop/share/classes/java/applet/Applet.java +++ b/src/java.desktop/share/classes/java/applet/Applet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -541,7 +541,7 @@ public void destroy() { // /** - * The accessible context associated with this {@code Applet}. + * @serial The accessible context associated with this {@code Applet}. */ @SuppressWarnings("serial") // Not statically typed as Serializable AccessibleContext accessibleContext = null; diff --git a/src/java.desktop/share/classes/java/awt/AWTEvent.java b/src/java.desktop/share/classes/java/awt/AWTEvent.java index 17c7b775c78..d48fae68cbe 100644 --- a/src/java.desktop/share/classes/java/awt/AWTEvent.java +++ b/src/java.desktop/share/classes/java/awt/AWTEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,7 +87,7 @@ public abstract class AWTEvent extends EventObject { /** - * The private data. + * @serial The private data. */ private byte[] bdata; diff --git a/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java b/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java index df38220d24c..fee1c9a4e19 100644 --- a/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java +++ b/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,22 +86,22 @@ public class AWTKeyStroke implements Serializable { private static AWTKeyStroke APP_CONTEXT_KEYSTROKE_KEY = new AWTKeyStroke(); /** - * The character value for a keyboard key. + * @serial The character value for a keyboard key. */ private char keyChar = KeyEvent.CHAR_UNDEFINED; /** - * The key code for this {@code AWTKeyStroke}. + * @serial The key code for this {@code AWTKeyStroke}. */ private int keyCode = KeyEvent.VK_UNDEFINED; /** - * The bitwise-ored combination of any modifiers. + * @serial The bitwise-ored combination of any modifiers. */ private int modifiers; /** - * {@code true} if this {@code AWTKeyStroke} corresponds to a key release; + * @serial {@code true} if this {@code AWTKeyStroke} corresponds to a key release; * {@code false} otherwise. */ private boolean onKeyRelease; diff --git a/src/java.desktop/share/classes/java/awt/Component.java b/src/java.desktop/share/classes/java/awt/Component.java index 8bfe16619bb..55fb06247af 100644 --- a/src/java.desktop/share/classes/java/awt/Component.java +++ b/src/java.desktop/share/classes/java/awt/Component.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -305,7 +305,7 @@ public abstract class Component implements ImageObserver, MenuContainer, volatile Font font; /** - * The font which the peer is currently using. + * @serial The font which the peer is currently using. * ({@code null} if no peer exists.) */ Font peerFont; @@ -508,7 +508,7 @@ static class AWTTreeLock {} Dimension minSize; /** - * Whether or not setMinimumSize has been invoked with a non-null value. + * @serial Whether or not setMinimumSize has been invoked with a non-null value. */ boolean minSizeSet; @@ -521,7 +521,7 @@ static class AWTTreeLock {} Dimension prefSize; /** - * Whether or not setPreferredSize has been invoked with a non-null value. + * @serial Whether or not setPreferredSize has been invoked with a non-null value. */ boolean prefSizeSet; @@ -533,7 +533,7 @@ static class AWTTreeLock {} Dimension maxSize; /** - * Whether or not setMaximumSize has been invoked with a non-null value. + * @serial Whether or not setMaximumSize has been invoked with a non-null value. */ boolean maxSizeSet; @@ -698,12 +698,12 @@ Object getObjectLock() { } /** - * Whether the component is packed or not; + * @serial Whether the component is packed or not; */ boolean isPacked = false; /** - * Pseudoparameter for direct Geometry API (setLocation, setBounds setSize + * @serial Pseudoparameter for direct Geometry API (setLocation, setBounds setSize * to signal setBounds what's changing. Should be used under TreeLock. * This is only needed due to the inability to change the cross-calling * order of public and deprecated methods. @@ -8290,7 +8290,7 @@ public boolean isFocusOwner() { } /** - * Used to disallow auto-focus-transfer on disposal of the focus owner + * @serial Used to disallow auto-focus-transfer on disposal of the focus owner * in the process of disposing its parent container. */ private boolean autoFocusTransferOnDisposal = true; @@ -9234,6 +9234,7 @@ Window getContainingWindow() { /** * The {@code AccessibleContext} associated with this {@code Component}. + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected AccessibleContext accessibleContext = null; @@ -9290,6 +9291,7 @@ protected AccessibleAWTComponent() { /** * A component listener to track show/hide/resize events * and convert them to PropertyChange events. + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected ComponentListener accessibleAWTComponentHandler = null; @@ -9297,6 +9299,7 @@ protected AccessibleAWTComponent() { /** * A listener to track focus events * and convert them to PropertyChange events. + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected FocusListener accessibleAWTFocusHandler = null; diff --git a/src/java.desktop/share/classes/java/awt/ComponentOrientation.java b/src/java.desktop/share/classes/java/awt/ComponentOrientation.java index afa1e8af94a..f12d4014ee9 100644 --- a/src/java.desktop/share/classes/java/awt/ComponentOrientation.java +++ b/src/java.desktop/share/classes/java/awt/ComponentOrientation.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -200,7 +200,7 @@ public static ComponentOrientation getOrientation(ResourceBundle bdl) } /** - * The bitwise-ored combination of flags. + * @serial The bitwise-ored combination of flags. */ private int orientation; diff --git a/src/java.desktop/share/classes/java/awt/Container.java b/src/java.desktop/share/classes/java/awt/Container.java index b6fbfb808a6..9bfb41a871e 100644 --- a/src/java.desktop/share/classes/java/awt/Container.java +++ b/src/java.desktop/share/classes/java/awt/Container.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -3853,6 +3853,7 @@ public Accessible getAccessibleAt(Point p) { /** * The handler to fire {@code PropertyChange} * when children are added or removed + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected ContainerListener accessibleContainerHandler = null; diff --git a/src/java.desktop/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java b/src/java.desktop/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java index 6f905f3d2c7..4183c3dc230 100644 --- a/src/java.desktop/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java +++ b/src/java.desktop/share/classes/java/awt/ContainerOrderFocusTraversalPolicy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,12 +66,12 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.ContainerOrderFocusTraversalPolicy"); /** - * This constant is used when the forward focus traversal order is active. + * @serial This constant is used when the forward focus traversal order is active. */ private final int FORWARD_TRAVERSAL = 0; /** - * This constant is used when the backward focus traversal order is active. + * @serial This constant is used when the backward focus traversal order is active. */ private final int BACKWARD_TRAVERSAL = 1; @@ -82,7 +82,7 @@ public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy private static final long serialVersionUID = 486933713763926351L; /** - * Whether this {@code ContainerOrderFocusTraversalPolicy} transfers focus + * @serial Whether this {@code ContainerOrderFocusTraversalPolicy} transfers focus * down-cycle implicitly. */ private boolean implicitDownCycleTraversal = true; diff --git a/src/java.desktop/share/classes/java/awt/FlowLayout.java b/src/java.desktop/share/classes/java/awt/FlowLayout.java index 3ad34f01776..18f46c54c0c 100644 --- a/src/java.desktop/share/classes/java/awt/FlowLayout.java +++ b/src/java.desktop/share/classes/java/awt/FlowLayout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -188,7 +188,7 @@ public class FlowLayout implements LayoutManager, java.io.Serializable { int vgap; /** - * If true, components will be aligned on their baseline. + * @serial If true, components will be aligned on their baseline. */ private boolean alignOnBaseline; diff --git a/src/java.desktop/share/classes/java/awt/Frame.java b/src/java.desktop/share/classes/java/awt/Frame.java index e01ef082d42..fcdb4d5e032 100644 --- a/src/java.desktop/share/classes/java/awt/Frame.java +++ b/src/java.desktop/share/classes/java/awt/Frame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -347,7 +347,7 @@ public class Frame extends Window implements MenuContainer { boolean mbManagement = false; /* used only by the Motif impl. */ /** - * The bitwise mask of frame state constants. + * @serial The bitwise mask of frame state constants. */ // XXX: uwe: abuse old field for now // will need to take care of serialization diff --git a/src/java.desktop/share/classes/java/awt/GridBagLayout.java b/src/java.desktop/share/classes/java/awt/GridBagLayout.java index 9fdd7ee7774..2dc65ab1265 100644 --- a/src/java.desktop/share/classes/java/awt/GridBagLayout.java +++ b/src/java.desktop/share/classes/java/awt/GridBagLayout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -473,7 +473,7 @@ public class GridBagLayout implements LayoutManager2, public double[] rowWeights; /** - * The component being positioned. This is set before calling into + * @serial The component being positioned. This is set before calling into * {@code adjustForGravity}. */ private Component componentAdjusting; diff --git a/src/java.desktop/share/classes/java/awt/GridBagLayoutInfo.java b/src/java.desktop/share/classes/java/awt/GridBagLayoutInfo.java index 1a4ed2942c5..ecdc4001369 100644 --- a/src/java.desktop/share/classes/java/awt/GridBagLayoutInfo.java +++ b/src/java.desktop/share/classes/java/awt/GridBagLayoutInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,37 +45,37 @@ public final class GridBagLayoutInfo implements java.io.Serializable { private static final long serialVersionUID = -4899416460737170217L; /** - * The number of cells: horizontal and vertical. + * @serial The number of cells: horizontal and vertical. */ int width, height; /** - * The starting point for layout. + * @serial The starting point for layout. */ int startx, starty; /** - * The largest minWidth in each column. + * @serial The largest minWidth in each column. */ int[] minWidth; /** - * The largest minHeight in each row. + * @serial The largest minHeight in each row. */ int[] minHeight; /** - * The largest weight in each column. + * @serial The largest weight in each column. */ double[] weightX; /** - * The largest weight in each row. + * @serial The largest weight in each row. */ double[] weightY; /** - * Whether or not baseline layout has been requested and one of the + * @serial Whether or not baseline layout has been requested and one of the * components has a valid baseline. */ boolean hasBaseline; @@ -83,18 +83,18 @@ public final class GridBagLayoutInfo implements java.io.Serializable { // These are only valid if hasBaseline is true and are indexed by // row. /** - * The type of baseline for a particular row. A mix of the + * @serial The type of baseline for a particular row. A mix of the * BaselineResizeBehavior constants {@code (1 << ordinal())} */ short[] baselineType; /** - * Max ascent (baseline). + * @serial Max ascent (baseline). */ int[] maxAscent; /** - * Max descent (height - baseline) + * @serial Max descent (height - baseline) */ int[] maxDescent; diff --git a/src/java.desktop/share/classes/java/awt/List.java b/src/java.desktop/share/classes/java/awt/List.java index fe7ebb58431..30b26aa371b 100644 --- a/src/java.desktop/share/classes/java/awt/List.java +++ b/src/java.desktop/share/classes/java/awt/List.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1552,12 +1552,12 @@ protected class AccessibleAWTListChild extends AccessibleAWTComponent // [[[FIXME]]] need to finish implementing this!!! /** - * The parent {@code List}. + * @serial The parent {@code List}. */ private List parent; /** - * The index in the parent. + * @serial The index in the parent. */ private int indexInParent; diff --git a/src/java.desktop/share/classes/java/awt/MenuComponent.java b/src/java.desktop/share/classes/java/awt/MenuComponent.java index facf995416f..1391a397f82 100644 --- a/src/java.desktop/share/classes/java/awt/MenuComponent.java +++ b/src/java.desktop/share/classes/java/awt/MenuComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -436,7 +436,7 @@ private void readObject(ObjectInputStream s) * --- Accessibility Support --- */ /** - * MenuComponent will contain all of the methods in interface Accessible, + * @serial MenuComponent will contain all of the methods in interface Accessible, * though it won't actually implement the interface - that will be up * to the individual objects which extend MenuComponent. */ diff --git a/src/java.desktop/share/classes/java/awt/ScrollPaneAdjustable.java b/src/java.desktop/share/classes/java/awt/ScrollPaneAdjustable.java index d8d70fd2476..9b539a311d3 100644 --- a/src/java.desktop/share/classes/java/awt/ScrollPaneAdjustable.java +++ b/src/java.desktop/share/classes/java/awt/ScrollPaneAdjustable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -140,7 +140,7 @@ public final class ScrollPaneAdjustable implements Adjustable, Serializable { private int blockIncrement = 1; /** - * Specified adjustment listener to receive adjustment events from this + * @serial Specified adjustment listener to receive adjustment events from this * {@code ScrollPaneAdjustable}. */ @SuppressWarnings("serial") // Not statically typed as Serializable diff --git a/src/java.desktop/share/classes/java/awt/TextComponent.java b/src/java.desktop/share/classes/java/awt/TextComponent.java index 5185646a07e..da722090afb 100644 --- a/src/java.desktop/share/classes/java/awt/TextComponent.java +++ b/src/java.desktop/share/classes/java/awt/TextComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,7 +115,7 @@ public sealed class TextComponent extends Component implements Accessible int selectionEnd; /** - * A flag used to tell whether the background has been set by + * @serial A flag used to tell whether the background has been set by * developer code (as opposed to AWT code). Used to determine * the background color of non-editable TextComponents. */ @@ -1207,7 +1207,7 @@ public String getBeforeIndex(int part, int index) { } // end of AccessibleAWTTextComponent /** - * Whether support of input methods should be checked or not. + * @serial Whether support of input methods should be checked or not. */ private boolean checkForEnableIM = true; } diff --git a/src/java.desktop/share/classes/java/awt/Window.java b/src/java.desktop/share/classes/java/awt/Window.java index 4e576f3dc9e..329e2574473 100644 --- a/src/java.desktop/share/classes/java/awt/Window.java +++ b/src/java.desktop/share/classes/java/awt/Window.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -229,7 +229,7 @@ public static enum Type { static boolean systemSyncLWRequests = false; /** - * Focus transfers should be synchronous for lightweight component requests. + * @serial Focus transfers should be synchronous for lightweight component requests. */ boolean syncLWRequests = false; transient boolean beforeFirstShow = true; @@ -2777,7 +2777,7 @@ private void removeFromWindowList() { } /** - * Window type. + * @serial Window type. * * Synchronization: ObjectLock */ @@ -3337,7 +3337,7 @@ boolean canContainFocusOwner(Component focusOwnerCandidate) { } /** - * {@code true} if this Window should appear at the default location, + * @serial {@code true} if this Window should appear at the default location, * {@code false} if at the current location. */ private volatile boolean locationByPlatform = locationByPlatformProp; diff --git a/src/java.desktop/share/classes/java/awt/color/ColorSpace.java b/src/java.desktop/share/classes/java/awt/color/ColorSpace.java index 80944e53017..2eab6aa46ef 100644 --- a/src/java.desktop/share/classes/java/awt/color/ColorSpace.java +++ b/src/java.desktop/share/classes/java/awt/color/ColorSpace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,12 +100,12 @@ public abstract class ColorSpace implements Serializable { private static final long serialVersionUID = -409452704308689724L; /** - * One of the {@code ColorSpace} type constants. + * @serial One of the {@code ColorSpace} type constants. */ private final int type; /** - * The number of components in the color space. + * @serial The number of components in the color space. */ private final int numComponents; diff --git a/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java b/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java index 56ea5c573d8..5a0af93cb5e 100644 --- a/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java +++ b/src/java.desktop/share/classes/java/awt/color/ICC_ColorSpace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,32 +88,32 @@ public class ICC_ColorSpace extends ColorSpace { private static final long serialVersionUID = 3455889114070431483L; /** - * The specified {@code ICC_Profile} object. + * @serial The specified {@code ICC_Profile} object. */ private ICC_Profile thisProfile; /** - * The minimum normalized component values. + * @serial The minimum normalized component values. */ private float[] minVal; /** - * The maximum normalized component values. + * @serial The maximum normalized component values. */ private float[] maxVal; /** - * Difference between min and max values. + * @serial Difference between min and max values. */ private float[] diffMinMax; /** - * Inverted value of the difference between min and max values. + * @serial Inverted value of the difference between min and max values. */ private float[] invDiffMinMax; /** - * Whether the values should be scaled or not. + * @serial Whether the values should be scaled or not. */ private boolean needScaleInit = true; diff --git a/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java b/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java index 3367d87456f..b7ce13abadc 100644 --- a/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java +++ b/src/java.desktop/share/classes/java/awt/desktop/FilesEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ public sealed class FilesEvent extends AppEvent private static final long serialVersionUID = 5271763715462312871L; /** - * The list of files. + * @serial The list of files. */ @SuppressWarnings("serial") // Not statically typed as Serializable final List files; diff --git a/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java b/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java index d815d867475..7c8ba561327 100644 --- a/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java +++ b/src/java.desktop/share/classes/java/awt/desktop/OpenFilesEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ public final class OpenFilesEvent extends FilesEvent { private static final long serialVersionUID = -3982871005867718956L; /** - * The search term used to find the files. + * @serial The search term used to find the files. */ final String searchTerm; diff --git a/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java b/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java index a1869d35fa3..f7e66065f54 100644 --- a/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java +++ b/src/java.desktop/share/classes/java/awt/desktop/OpenURIEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,7 @@ public final class OpenURIEvent extends AppEvent { private static final long serialVersionUID = 221209100935933476L; /** - * The {@code URI} the app was asked to open. + * @serial The {@code URI} the app was asked to open. */ final URI uri; diff --git a/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java b/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java index 9199358b688..4cb011c05f5 100644 --- a/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java +++ b/src/java.desktop/share/classes/java/awt/desktop/UserSessionEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,7 @@ public final class UserSessionEvent extends AppEvent { private static final long serialVersionUID = 6747138462796569055L; /** - * The reason of the user session change. + * @serial The reason of the user session change. */ private final Reason reason; diff --git a/src/java.desktop/share/classes/java/awt/event/HierarchyEvent.java b/src/java.desktop/share/classes/java/awt/event/HierarchyEvent.java index 0588706df7a..ae463369f38 100644 --- a/src/java.desktop/share/classes/java/awt/event/HierarchyEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/HierarchyEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -166,18 +166,18 @@ public class HierarchyEvent extends AWTEvent { public static final int SHOWING_CHANGED = 0x4; /** - * The {@code Component} at the top of the hierarchy which was changed. + * @serial The {@code Component} at the top of the hierarchy which was changed. */ Component changed; /** - * The parent of the {@code changed} component. This may be the parent + * @serial The parent of the {@code changed} component. This may be the parent * before or after the change, depending on the type of change. */ Container changedParent; /** - * A bitmask which indicates the type(s) of the {@code HIERARCHY_CHANGED} + * @serial A bitmask which indicates the type(s) of the {@code HIERARCHY_CHANGED} * events represented in this event object. For information on allowable * values, see the class description for {@link HierarchyEvent} */ diff --git a/src/java.desktop/share/classes/java/awt/event/InvocationEvent.java b/src/java.desktop/share/classes/java/awt/event/InvocationEvent.java index c73b77282d5..b9966af5865 100644 --- a/src/java.desktop/share/classes/java/awt/event/InvocationEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/InvocationEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,6 +85,8 @@ public void dispose(InvocationEvent invocationEvent) { /** * The Runnable whose run() method will be called. + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected Runnable runnable; @@ -95,12 +97,13 @@ public void dispose(InvocationEvent invocationEvent) { * or after the event was disposed. * * @see #isDispatched + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected volatile Object notifier; /** - * The (potentially null) Runnable whose run() method will be called + * @serial The (potentially null) Runnable whose run() method will be called * immediately after the event was dispatched or disposed. * * @see #isDispatched @@ -110,7 +113,7 @@ public void dispose(InvocationEvent invocationEvent) { private final Runnable listener; /** - * Indicates whether the {@code run()} method of the {@code runnable} + * @serial Indicates whether the {@code run()} method of the {@code runnable} * was executed or not. * * @see #isDispatched @@ -122,18 +125,20 @@ public void dispose(InvocationEvent invocationEvent) { * Set to true if dispatch() catches Throwable and stores it in the * exception instance variable. If false, Throwables are propagated up * to the EventDispatchThread's dispatch loop. + * + * @serial */ protected boolean catchExceptions; /** - * The (potentially null) Exception thrown during execution of the + * @serial The (potentially null) Exception thrown during execution of the * Runnable.run() method. This variable will also be null if a particular * instance does not catch exceptions. */ private Exception exception = null; /** - * The (potentially null) Throwable thrown during execution of the + * @serial The (potentially null) Throwable thrown during execution of the * Runnable.run() method. This variable will also be null if a particular * instance does not catch exceptions. */ diff --git a/src/java.desktop/share/classes/java/awt/event/KeyEvent.java b/src/java.desktop/share/classes/java/awt/event/KeyEvent.java index abc1082d5bd..7470a23881e 100644 --- a/src/java.desktop/share/classes/java/awt/event/KeyEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/KeyEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -154,7 +154,7 @@ public non-sealed class KeyEvent extends InputEvent { /** - * Stores the state of native event dispatching system + * @serial Stores the state of native event dispatching system * - true, if when the event was created event proxying * mechanism was active * - false, if it was inactive @@ -1229,7 +1229,7 @@ public boolean isProxyActive(KeyEvent ev) { private static native void initIDs(); /** - * The original event source. + * @serial The original event source. * * Event source can be changed during processing, but in some cases * we need to be able to obtain original source. diff --git a/src/java.desktop/share/classes/java/awt/event/MouseEvent.java b/src/java.desktop/share/classes/java/awt/event/MouseEvent.java index 56ac76eeaff..cabcb7b1d7d 100644 --- a/src/java.desktop/share/classes/java/awt/event/MouseEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/MouseEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -334,7 +334,7 @@ public non-sealed class MouseEvent extends InputEvent { int clickCount; /** - * Indicates whether the event is a result of a touch event. + * @serial Indicates whether the event is a result of a touch event. */ private boolean causedByTouchEvent; diff --git a/src/java.desktop/share/classes/java/awt/event/MouseWheelEvent.java b/src/java.desktop/share/classes/java/awt/event/MouseWheelEvent.java index 37efe0a04d7..33a357888dd 100644 --- a/src/java.desktop/share/classes/java/awt/event/MouseWheelEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/MouseWheelEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,7 +118,7 @@ public class MouseWheelEvent extends MouseEvent { @Native public static final int WHEEL_BLOCK_SCROLL = 1; /** - * Indicates what sort of scrolling should take place in response to this + * @serial Indicates what sort of scrolling should take place in response to this * event, based on platform settings. Legal values are: *

        *
      • WHEEL_UNIT_SCROLL @@ -130,7 +130,7 @@ public class MouseWheelEvent extends MouseEvent { int scrollType; /** - * Only valid for scrollType WHEEL_UNIT_SCROLL. + * @serial Only valid for scrollType WHEEL_UNIT_SCROLL. * Indicates number of units that should be scrolled per * click of mouse wheel rotation, based on platform settings. * @@ -140,14 +140,14 @@ public class MouseWheelEvent extends MouseEvent { int scrollAmount; /** - * Indicates how far the mouse wheel was rotated. + * @serial Indicates how far the mouse wheel was rotated. * * @see #getWheelRotation */ int wheelRotation; /** - * Indicates how far the mouse wheel was rotated. + * @serial Indicates how far the mouse wheel was rotated. * * @see #getPreciseWheelRotation */ diff --git a/src/java.desktop/share/classes/java/awt/event/WindowEvent.java b/src/java.desktop/share/classes/java/awt/event/WindowEvent.java index 51370170e51..d898860f153 100644 --- a/src/java.desktop/share/classes/java/awt/event/WindowEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/WindowEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -165,12 +165,12 @@ public class WindowEvent extends ComponentEvent { transient Window opposite; /** - * Previous state of the window for window state change event. + * @serial Previous state of the window for window state change event. */ int oldState; /** - * New state of the window for window state change event. + * @serial New state of the window for window state change event. */ int newState; diff --git a/src/java.desktop/share/classes/java/awt/font/NumericShaper.java b/src/java.desktop/share/classes/java/awt/font/NumericShaper.java index c12d63e9951..ae507036112 100644 --- a/src/java.desktop/share/classes/java/awt/font/NumericShaper.java +++ b/src/java.desktop/share/classes/java/awt/font/NumericShaper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -393,16 +393,16 @@ private boolean inRange(int c) { } } - /** index of context for contextual shaping - values range from 0 to 18 */ + /** @serial index of context for contextual shaping - values range from 0 to 18 */ private int key; - /** flag indicating whether to shape contextually (high bit) and which + /** @serial flag indicating whether to shape contextually (high bit) and which * digit ranges to shape (bits 0-18) */ private int mask; /** - * The context {@code Range} for contextual shaping or the {@code + * @serial The context {@code Range} for contextual shaping or the {@code * Range} for non-contextual shaping. {@code null} for the bit * mask-based API. * diff --git a/src/java.desktop/share/classes/java/awt/font/TransformAttribute.java b/src/java.desktop/share/classes/java/awt/font/TransformAttribute.java index 2dd25eec4d8..9bcf83ddc83 100644 --- a/src/java.desktop/share/classes/java/awt/font/TransformAttribute.java +++ b/src/java.desktop/share/classes/java/awt/font/TransformAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ public final class TransformAttribute implements Serializable { /** - * The {@code AffineTransform} for this + * @serial The {@code AffineTransform} for this * {@code TransformAttribute}, or {@code null} * if {@code AffineTransform} is the identity transform. */ diff --git a/src/java.desktop/share/classes/java/awt/image/renderable/ParameterBlock.java b/src/java.desktop/share/classes/java/awt/image/renderable/ParameterBlock.java index 10f62777526..c98a5b2c771 100644 --- a/src/java.desktop/share/classes/java/awt/image/renderable/ParameterBlock.java +++ b/src/java.desktop/share/classes/java/awt/image/renderable/ParameterBlock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -102,10 +102,16 @@ public class ParameterBlock implements Cloneable, Serializable { @Serial private static final long serialVersionUID = -7577115551785240750L; - /** A Vector of sources, stored as arbitrary Objects. */ + /** + * A Vector of sources, stored as arbitrary Objects. + * @serial + */ protected Vector sources = new Vector(); - /** A Vector of non-source parameters, stored as arbitrary Objects. */ + /** + * A Vector of non-source parameters, stored as arbitrary Objects. + * @serial + */ protected Vector parameters = new Vector(); /** A dummy constructor. */ diff --git a/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java b/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java index 983dd810079..90c0fb109d2 100644 --- a/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java +++ b/src/java.desktop/share/classes/java/beans/IndexedPropertyChangeEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,7 @@ public class IndexedPropertyChangeEvent extends PropertyChangeEvent { private static final long serialVersionUID = -320227448495806870L; /** - * The index of the property element that was changed. + * @serial The index of the property element that was changed. */ private int index; diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildSupport.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildSupport.java index 532661dc29b..527a8be9cc0 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildSupport.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -358,6 +358,8 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound /** * The {@code BeanContext} in which * this {@code BeanContextChild} is nested. + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable public BeanContextChild beanContextChildPeer; @@ -365,12 +367,16 @@ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFound /** * The {@code PropertyChangeSupport} associated with this * {@code BeanContextChildSupport}. + * + * @serial */ protected PropertyChangeSupport pcSupport; /** * The {@code VetoableChangeSupport} associated with this * {@code BeanContextChildSupport}. + * + * @serial */ protected VetoableChangeSupport vcSupport; diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextEvent.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextEvent.java index 62fd45eee79..1b600bc29b4 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextEvent.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,6 +105,8 @@ public synchronized boolean isPropagated() { /** * The {@code BeanContext} from which this event was propagated + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected BeanContext propagatedFrom; diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java index 5c5d112d36a..ab63aae86e5 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextMembershipEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -133,6 +133,8 @@ public boolean contains(Object child) { /** * The list of children affected by this * event notification. + * + * @serial */ @SuppressWarnings({"rawtypes", "serial"}) // Not statically typed as Serializable diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceAvailableEvent.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceAvailableEvent.java index dd4cc457a31..b2132ad8f97 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceAvailableEvent.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceAvailableEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,6 +84,8 @@ public Iterator getCurrentServiceSelectors() { /** * A {@code Class} reference to the newly available service + * + * @serial */ protected Class serviceClass; } diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceRevokedEvent.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceRevokedEvent.java index d32b18376a4..6ef996b3482 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceRevokedEvent.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceRevokedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -99,11 +99,13 @@ public boolean isServiceClass(Class service) { /** * A {@code Class} reference to the service that is being revoked. + * + * @serial */ protected Class serviceClass; /** - * {@code true} if current service is being forcibly revoked. + * @serial {@code true} if current service is being forcibly revoked. */ private boolean invalidateRefs; } diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java index 98d68d92fa1..0e2e4211a9c 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServicesSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -627,6 +627,8 @@ protected BeanContextServiceProvider getServiceProvider() { /** * The service provider. + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected BeanContextServiceProvider serviceProvider; diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java index fedd6667de1..dbbecb87d7e 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -342,13 +342,13 @@ protected class BCSChild implements Serializable { /** - * The child. + * @serial The child. */ @SuppressWarnings("serial") // Not statically typed as Serializable private Object child; /** - * The peer if the child and the peer are related by an implementation + * @serial The peer if the child and the peer are related by an implementation * of BeanContextProxy */ @SuppressWarnings("serial") // Not statically typed as Serializable @@ -1393,7 +1393,7 @@ protected static final boolean classEquals(Class first, Class second) { protected transient HashMap children; /** - * Currently serializable children. + * @serial Currently serializable children. */ private int serializable = 0; // children serializable @@ -1407,12 +1407,16 @@ protected static final boolean classEquals(Class first, Class second) { /** * The current locale of this BeanContext. + * + * @serial */ protected Locale locale; /** * A {@code boolean} indicating if this * instance may now render a GUI. + * + * @serial */ protected boolean okToUseGui; @@ -1420,6 +1424,8 @@ protected static final boolean classEquals(Class first, Class second) { /** * A {@code boolean} indicating whether or not * this object is currently in design time mode. + * + * @serial */ protected boolean designTime; diff --git a/src/java.desktop/share/classes/javax/imageio/metadata/IIOInvalidTreeException.java b/src/java.desktop/share/classes/javax/imageio/metadata/IIOInvalidTreeException.java index 2c851ec2f0e..bc14958de1c 100644 --- a/src/java.desktop/share/classes/javax/imageio/metadata/IIOInvalidTreeException.java +++ b/src/java.desktop/share/classes/javax/imageio/metadata/IIOInvalidTreeException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,6 +57,8 @@ public class IIOInvalidTreeException extends IIOException { /** * The {@code Node} that led to the parsing error, or * {@code null}. + * + * @serial */ @SuppressWarnings("serial") // Not statically typed as Serializable protected Node offendingNode = null; diff --git a/src/java.desktop/share/classes/javax/print/attribute/AttributeSetUtilities.java b/src/java.desktop/share/classes/javax/print/attribute/AttributeSetUtilities.java index 9244c12270a..f762eb89925 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/AttributeSetUtilities.java +++ b/src/java.desktop/share/classes/javax/print/attribute/AttributeSetUtilities.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -86,7 +86,7 @@ private static class UnmodifiableAttributeSet private static final long serialVersionUID = -6131802583863447813L; /** - * The attribute set. + * @serial The attribute set. */ @SuppressWarnings("serial") // Not statically typed as Serializable private AttributeSet attrset; @@ -352,7 +352,7 @@ private static class SynchronizedAttributeSet private static final long serialVersionUID = 8365731020128564925L; /** - * The attribute set. + * @serial The attribute set. */ @SuppressWarnings("serial") // Not statically typed as Serializable private AttributeSet attrset; diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java b/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java index 807eaa2b122..593e656cf6b 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/DialogOwner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,7 +67,7 @@ public long getOwnerID(DialogOwner owner) { private static final long serialVersionUID = -1901909867156076547L; /** - * The owner of the dialog. + * @serial The owner of the dialog. */ private Window owner; private transient long id; diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/MediaPrintableArea.java b/src/java.desktop/share/classes/javax/print/attribute/standard/MediaPrintableArea.java index c1d16c23154..72a58f2b697 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/MediaPrintableArea.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/MediaPrintableArea.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -85,12 +85,12 @@ public final class MediaPrintableArea implements DocAttribute, PrintRequestAttribute, PrintJobAttribute { /** - * Printable {@code x}, {@code y}, {@code width} and {@code height}. + * @serial Printable {@code x}, {@code y}, {@code width} and {@code height}. */ private int x, y, w, h; /** - * The units in which the values are expressed. + * @serial The units in which the values are expressed. */ private int units; diff --git a/src/java.desktop/share/classes/javax/print/attribute/standard/MediaSize.java b/src/java.desktop/share/classes/javax/print/attribute/standard/MediaSize.java index bf33eabafac..6a8db3b94c2 100644 --- a/src/java.desktop/share/classes/javax/print/attribute/standard/MediaSize.java +++ b/src/java.desktop/share/classes/javax/print/attribute/standard/MediaSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,7 +60,7 @@ public class MediaSize extends Size2DSyntax implements Attribute { private static final long serialVersionUID = -1967958664615414771L; /** - * The media name. + * @serial The media name. */ private MediaSizeName mediaName; diff --git a/src/java.desktop/share/classes/javax/print/event/PrintJobAttributeEvent.java b/src/java.desktop/share/classes/javax/print/event/PrintJobAttributeEvent.java index ec244468c19..717898d8c50 100644 --- a/src/java.desktop/share/classes/javax/print/event/PrintJobAttributeEvent.java +++ b/src/java.desktop/share/classes/javax/print/event/PrintJobAttributeEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ public class PrintJobAttributeEvent extends PrintEvent { private static final long serialVersionUID = -6534469883874742101L; /** - * The printing service attributes that changed. + * @serial The printing service attributes that changed. */ @SuppressWarnings("serial") // Not statically typed as Serializable private PrintJobAttributeSet attributes; diff --git a/src/java.desktop/share/classes/javax/print/event/PrintJobEvent.java b/src/java.desktop/share/classes/javax/print/event/PrintJobEvent.java index f68e2df5a03..629a487e04a 100644 --- a/src/java.desktop/share/classes/javax/print/event/PrintJobEvent.java +++ b/src/java.desktop/share/classes/javax/print/event/PrintJobEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ public class PrintJobEvent extends PrintEvent { private static final long serialVersionUID = -1711656903622072997L; /** - * The reason of this event. + * @serial The reason of this event. */ private int reason; diff --git a/src/java.desktop/share/classes/javax/print/event/PrintServiceAttributeEvent.java b/src/java.desktop/share/classes/javax/print/event/PrintServiceAttributeEvent.java index 4281c31b397..6cdc22246df 100644 --- a/src/java.desktop/share/classes/javax/print/event/PrintServiceAttributeEvent.java +++ b/src/java.desktop/share/classes/javax/print/event/PrintServiceAttributeEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ public class PrintServiceAttributeEvent extends PrintEvent { private static final long serialVersionUID = -7565987018140326600L; /** - * The printing service attributes that changed. + * @serial The printing service attributes that changed. */ @SuppressWarnings("serial") // Not statically typed as Serializable private PrintServiceAttributeSet attributes; From bdd600078b016a732fdb4fdbc21470793379cac3 Mon Sep 17 00:00:00 2001 From: Alisen Chung Date: Thu, 9 Jan 2025 21:51:51 +0000 Subject: [PATCH 23/25] 8347375: Extra

        tag in robot specification Reviewed-by: kbarrett --- src/java.desktop/share/classes/java/awt/Robot.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.desktop/share/classes/java/awt/Robot.java b/src/java.desktop/share/classes/java/awt/Robot.java index d0877b3bddd..957e30126e1 100644 --- a/src/java.desktop/share/classes/java/awt/Robot.java +++ b/src/java.desktop/share/classes/java/awt/Robot.java @@ -57,7 +57,7 @@ * events are generated in the platform's native input * queue. For example, {@code Robot.mouseMove} will actually move * the mouse cursor instead of just generating mouse move events. - *

        + * * @apiNote When {@code autoWaitForIdle()} is enabled, mouse and key related methods * cannot be called on the AWT EDT. This is because when {@code autoWaitForIdle()} * is enabled, the mouse and key methods implicitly call {@code waitForIdle()} @@ -666,7 +666,7 @@ public synchronized boolean isAutoWaitForIdle() { /** * Sets whether this Robot automatically invokes {@code waitForIdle} * after generating an event. - *

        + * * @apiNote Setting this to true means you cannot call mouse and key-controlling events * on the AWT Event Dispatching Thread * From 925b22605a7c463fb7bb856e245fadaf70f99255 Mon Sep 17 00:00:00 2001 From: Fei Yang Date: Fri, 10 Jan 2025 00:26:38 +0000 Subject: [PATCH 24/25] 8346787: Fix two C2 IR matching tests for RISC-V Reviewed-by: fjiang, mli, dfenacci --- .../compiler/c2/irTests/ModINodeIdealizationTests.java | 8 +++++--- .../compiler/c2/irTests/ModLNodeIdealizationTests.java | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/test/hotspot/jtreg/compiler/c2/irTests/ModINodeIdealizationTests.java b/test/hotspot/jtreg/compiler/c2/irTests/ModINodeIdealizationTests.java index 2437b05586a..dffafea7ea8 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/ModINodeIdealizationTests.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/ModINodeIdealizationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -121,8 +121,10 @@ public int powerOf2Random(int x) { } @Test - @IR(failOn = {IRNode.MOD_I}) - @IR(counts = {IRNode.AND_I, ">=1", IRNode.RSHIFT, ">=1", IRNode.CMP_I, "2"}) + @IR(applyIfPlatform = {"riscv64", "false"}, + failOn = {IRNode.MOD_I}) + @IR(applyIfPlatform = {"riscv64", "false"}, + counts = {IRNode.AND_I, ">=1", IRNode.RSHIFT, ">=1", IRNode.CMP_I, "2"}) // Special optimization for the case 2^k-1 for bigger k public int powerOf2Minus1(int x) { return x % 127; diff --git a/test/hotspot/jtreg/compiler/c2/irTests/ModLNodeIdealizationTests.java b/test/hotspot/jtreg/compiler/c2/irTests/ModLNodeIdealizationTests.java index 515a7d535f4..e931ff87c09 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/ModLNodeIdealizationTests.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/ModLNodeIdealizationTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,8 +105,10 @@ public long powerOf2Random(long x) { } @Test - @IR(failOn = {IRNode.MOD_L}) - @IR(counts = {IRNode.AND_L, ">=1", IRNode.RSHIFT, ">=1", IRNode.CMP_L, "2"}) + @IR(applyIfPlatform = {"riscv64", "false"}, + failOn = {IRNode.MOD_L}) + @IR(applyIfPlatform = {"riscv64", "false"}, + counts = {IRNode.AND_L, ">=1", IRNode.RSHIFT, ">=1", IRNode.CMP_L, "2"}) // Special optimization for the case 2^k-1 for bigger k public long powerOf2Minus1(long x) { return x % ((1L << 33) - 1); From eaee1d8b95fe1002e513fe65fd50988b264cb75c Mon Sep 17 00:00:00 2001 From: Henry Jen Date: Fri, 10 Jan 2025 00:53:58 +0000 Subject: [PATCH 25/25] 8347379: Problem list failed tests after JDK-8321413 Reviewed-by: dholmes --- test/jdk/ProblemList.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 6a2ab0d1e04..b82d661bd2d 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -716,6 +716,8 @@ javax/swing/plaf/synth/7158712/bug7158712.java 8324782 macosx-all # core_tools +tools/jlink/runtimeImage/JavaSEReproducibleTest.java 8347376 generic-all +tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java 8347376 generic-all ############################################################################